首頁常見問題正文

notify()和notifyAll()的區(qū)別是什么?

更新時(shí)間:2023-10-27 來源:黑馬程序員 瀏覽量:

IT培訓(xùn)班

  notify()和notifyAll()都是Java中用于多線程編程的方法,用于在多線程環(huán)境中管理線程的等待和喚醒操作。它們的主要區(qū)別在于喚醒的目標(biāo)線程數(shù)以及線程等待的條件。

  1.notify()

  notify()方法用于喚醒等待在對象上的一個(gè)隨機(jī)線程。如果多個(gè)線程在同一個(gè)對象上等待,那么只有其中的一個(gè)線程會(huì)被喚醒,但無法確定是哪一個(gè)線程。這個(gè)方法通常用于線程之間的競爭條件,其中只有一個(gè)線程能夠獲得資源的情況。

  示例代碼:

class SharedResource {
    public synchronized void doSomething() {
        System.out.println("Thread " + Thread.currentThread().getId() + " is working.");
        notify(); // 喚醒等待的線程
    }
}

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è)等待的線程
    }
}

  在上面的示例中,notify()喚醒了其中一個(gè)等待的線程,但不能確定是哪一個(gè)線程被喚醒。

  2.notifyAll()

  notifyAll()方法用于喚醒等待在對象上的所有線程。這意味著所有等待的線程都有機(jī)會(huì)爭奪資源。這通常用于廣播消息或者在共享資源可用時(shí)喚醒所有等待線程的情況。

1698374058708_notify()和notifyAll()的區(qū)別是什么.jpg

  示例代碼:

class SharedResource {
    public synchronized void doSomething() {
        System.out.println("Thread " + Thread.currentThread().getId() + " is working.");
        notifyAll(); // 喚醒所有等待的線程
    }
}

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(); // 喚醒所有等待的線程
    }
}

  在上面的示例中,notifyAll()喚醒了所有等待的線程,它們都有機(jī)會(huì)爭奪資源。

  總結(jié):

  (1)notify()喚醒一個(gè)等待的線程,選擇喚醒哪個(gè)線程不確定。

  (2)notifyAll()喚醒所有等待的線程,它們都有機(jī)會(huì)爭奪資源。

分享到:
在線咨詢 我要報(bào)名
和我們在線交談!