更新時(shí)間:2023-10-27 來(lái)源:黑馬程序員 瀏覽量:
notify()和notifyAll()都是Java中用于多線(xiàn)程編程的方法,用于在多線(xiàn)程環(huán)境中管理線(xiàn)程的等待和喚醒操作。它們的主要區(qū)別在于喚醒的目標(biāo)線(xiàn)程數(shù)以及線(xiàn)程等待的條件。
notify()方法用于喚醒等待在對(duì)象上的一個(gè)隨機(jī)線(xiàn)程。如果多個(gè)線(xiàn)程在同一個(gè)對(duì)象上等待,那么只有其中的一個(gè)線(xiàn)程會(huì)被喚醒,但無(wú)法確定是哪一個(gè)線(xiàn)程。這個(gè)方法通常用于線(xiàn)程之間的競(jìng)爭(zhēng)條件,其中只有一個(gè)線(xiàn)程能夠獲得資源的情況。
示例代碼:
class SharedResource { public synchronized void doSomething() { System.out.println("Thread " + Thread.currentThread().getId() + " is working."); notify(); // 喚醒等待的線(xiàn)程 } } public class NotifyExample { public static void main(String[] args) { SharedResource resource = new SharedResource(); Runnable task = () -> { synchronized (resource) { try { System.out.println("Thread " + Thread.currentThread().getId() + " is waiting."); resource.wait(); // 等待資源 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread " + Thread.currentThread().getId() + " is awake."); } }; Thread thread1 = new Thread(task); Thread thread2 = new Thread(task); thread1.start(); thread2.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } resource.doSomething(); // 喚醒一個(gè)等待的線(xiàn)程 } }
在上面的示例中,notify()喚醒了其中一個(gè)等待的線(xiàn)程,但不能確定是哪一個(gè)線(xiàn)程被喚醒。
notifyAll()方法用于喚醒等待在對(duì)象上的所有線(xiàn)程。這意味著所有等待的線(xiàn)程都有機(jī)會(huì)爭(zhēng)奪資源。這通常用于廣播消息或者在共享資源可用時(shí)喚醒所有等待線(xiàn)程的情況。
示例代碼:
class SharedResource { public synchronized void doSomething() { System.out.println("Thread " + Thread.currentThread().getId() + " is working."); notifyAll(); // 喚醒所有等待的線(xiàn)程 } } public class NotifyAllExample { public static void main(String[] args) { SharedResource resource = new SharedResource(); Runnable task = () -> { synchronized (resource) { try { System.out.println("Thread " + Thread.currentThread().getId() + " is waiting."); resource.wait(); // 等待資源 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread " + Thread.currentThread().getId() + " is awake."); } }; Thread thread1 = new Thread(task); Thread thread2 = new Thread(task); thread1.start(); thread2.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } resource.doSomething(); // 喚醒所有等待的線(xiàn)程 } }
在上面的示例中,notifyAll()喚醒了所有等待的線(xiàn)程,它們都有機(jī)會(huì)爭(zhēng)奪資源。
總結(jié):
(1)notify()喚醒一個(gè)等待的線(xiàn)程,選擇喚醒哪個(gè)線(xiàn)程不確定。
(2)notifyAll()喚醒所有等待的線(xiàn)程,它們都有機(jī)會(huì)爭(zhēng)奪資源。