一、notify和notifyAll方法的作用
Java中的notify和notifyAll方法是用於線程間通信的機制。在多個線程共同競爭一個鎖對象時,當該鎖對象被其中一個線程佔用時,其他線程需要等待,直到佔用該鎖對象的線程釋放鎖。而notify和notifyAll方法可以用來通知其他線程,告知它們可以再次競爭鎖對象了。
二、notify和notifyAll方法的區別
notify方法會隨機選擇一個正在等待該鎖對象的線程進行喚醒,而notifyAll方法會喚醒所有正在等待該鎖對象的線程。
public class TestNotify {
private static final Object lock = new Object();
public static void main(String[] args) {
Thread thread1 = new Thread(new WaitThread(), "wait-thread-1");
Thread thread2 = new Thread(new WaitThread(), "wait-thread-2");
Thread thread3 = new Thread(new NotifyThread(), "notify-thread");
thread1.start();
thread2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread3.start();
}
static class WaitThread implements Runnable {
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " enter synchronized block");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " leave synchronized block");
}
}
}
static class NotifyThread implements Runnable {
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " enter synchronized block");
lock.notifyAll();
System.out.println(Thread.currentThread().getName() + " leave synchronized block");
}
}
}
}
三、notify和notifyAll方法的使用場景
在實際應用中,notify和notifyAll方法一般用於生產者消費者模型中,用來喚醒等待隊列中的消費者線程。在生產者消費者模型中,當生產者向隊列中放入數據時,如果隊列已經滿了,就需要喚醒正在等待的消費者線程;當消費者從隊列中取出數據時,如果隊列已經空了,就需要喚醒正在等待的生產者線程。
public class WaitNotifyExample {
public static void main(String[] args) {
Queue queue = new PriorityQueue();
Thread producer = new Thread(() -> {
for (int i = 0; i {
while (true) {
synchronized (queue) {
while (queue.isEmpty()) {
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int number = queue.poll();
System.out.println("Consumer: " + number);
queue.notifyAll();
}
}
});
producer.start();
consumer.start();
}
}
四、notify和notifyAll方法的注意事項
在使用notify和notifyAll方法時,需要注意以下事項:
1. 必須在同步塊中調用notify和notifyAll方法,否則會拋出IllegalMonitorStateException異常;
2. 如果使用notify方法,則在多線程競爭鎖時並不能保證哪個線程會收到通知,因此一般使用notifyAll方法;
3. notify和notifyAll方法並不是真正釋放鎖,只是喚醒等待隊列中的線程,當前線程還需要執行完同步塊才會釋放鎖。
原創文章,作者:NKSD,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/147728.html
微信掃一掃
支付寶掃一掃