一、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