How to notify a specific thread in Java

后端 未结 4 821
闹比i
闹比i 2020-12-21 04:07

How I can call a particular thread in inter-thread communication?

In the program below I have two threads t1 and t2.

When I call

4条回答
  •  误落风尘
    2020-12-21 04:56

    To add some points;

    Your code is using intrinsic locks. Every object in the JVM has its own lock. This lock has nothing to do with the functionality of the object. Acquiring the lock by itself does nothing (in the absence of further measures like using the synchronized keyword) to prevent other threads from monkeying with the object's contents. Calling notify on a thread does not mean that that particular thread will receive a notification.

    As said previously acquiring the lock on Thread objects is discouraged. The join method on Thread uses the intrinsic lock on the thread joined to. If code acquires a lock for different reasons then a thread can be notified for some condition that it may not care about.

    The intrinsic lock is a go-between that tells the OS scheduler which threads are waiting. The OS scheduler decides which threads in the wait set for the lock get notified. When a thread calls notify on an object, it is telling the lock on that object to tell the scheduler to choose which waiting thread gets notified. The lock knows which threads are waiting but it doesn't know what condition they're waiting for. (ReentrantLock is a big improvement for this, see the API doc for Condition.)

    Of course notifyAll wakes up all the threads in the wait set, but again that is something the lock and the scheduler know. The thread calling notifyAll doesn't know about what threads are waiting. The system is designed intentionally so that threads cannot notify other threads directly.

    Yet another thing here is that calling wait with no check for a condition is unreliable. If a thread doesn't happen to have acquired a lock before a notification is made, it misses that notification. If a thread receives a notification, that is no guarantee it will get the lock next, another thread could act and invalidate the state that the notified thread is expecting. Always have some internal state that the current thread can check to verify that the object's state is what the thread is expecting, and make that check as the test in a loop.

    For instance if I have a fixed size blocking queue (implemented using a list internally, protecting it from concurrent access using synchronization) where threads try to take something from the queue but block if the queue is empty, the take method could look like:

    public synchronized T take() throws InterruptedException {
        while (list.isEmpty()) {
            wait();
        }
        notifyAll();
        return list.remove(0);
    }
    

    Once a waiting thread wakes and reacquires the lock, it checks to see if the current situation is what it has been waiting for. Only if that is the case should the thread exit the loop and proceed.

提交回复
热议问题