Lecture on Java Concurrency Day 1 on Jan 21, 2009. (in Korean)
Lectures are 4 days in all.
See http://javadom.blogspot.com/2011/06/lecture-on-java-concurrency-day-1.html
10. 1-3 Thread Revisited Spurious wakeup Notify or notifyAll Volatile and visibility
11.
12.
13.
Notas do Editor
Quiz : 두 개 ( 혹은 여러 개 ) 의 쓰레드가 동시에 다음 코드를 실행할 때 value 가 가질 수 있는 가능한 값은 ? (value 의 초기값은 0) public void run() { while (true) { value = value + 5; value = value - 5; } }
Lock 인터페이스는 자바의 동기화 블럭 표현 방식인 synchronized 블럭 대신에 명시적인 잠금 획득과 잠금 해제를 사용하는 방식이다 . C/C++ 에서 제공하는 잠금 방식과 유사한 방식으로 코드 차원에서 잠금을 반드시 풀어줘야 한다는 제약이 있지만 블럭 구조가 아닌 방식 , 즉 필요에 따라 잠금 획득과 잠금 해제가 완전히 다른 메쏘드나 블럭에서 처리될 수도 있으며 , 잠금을 획득할 때 tryLock() 을 사용할 수 있다는 장점이 있다 . Condition 인터페이스는 자바의 동기화 이벤트 표현 방식인 wait(), notify() 메쏘드에 대응하는 개념으로 wait(), notify() 메쏘드들이 대응하는 synchronized 블럭 안에서 동작하듯이 Condition 객체는 대응하는 Lock 객체를 통해 동작한다 . Condition 객체를 사용할 때의 장점으로는 하나의 Lock 객체에서 여러 개의 Condition 객체를 사용할 수 있다는 점을 들 수 있다 . class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#wait() A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one: synchronized (obj) { while () obj.wait(timeout); ... // Perform action appropriate to condition }
Possible Notify Cases All possible waiting threads are necessarily waiting for conditions relying on the same notifications, usually the exact same condition Each notification intrinsically enables at most a single thread to continue. Thus it would be useless to wake up others. Can accommodate uncertainties surrounding the possibility that an interrupt and a notify may occur at about the same time. In this case, the one thread that was notified is about to terminate. You might want another thread to receive notification instead, but this is not automatically arranged. (The issue does not arise with notifyAll since all threads are woken)