📜  Javanotify()和notifyAll()的区别(1)

📅  最后修改于: 2023-12-03 15:31:36.473000             🧑  作者: Mango

Javanotify()和notifyAll()的区别

在Java中,一个线程可以通过等待来等待另一个线程发出通知。当线程等待时,它进入睡眠状态,并释放其持有的锁。当它被通知时,它会醒来并重新请求锁。Java提供了两种方法来通知等待中的线程:notify()和notifyAll()。

Javanotify()

notify()方法是唯一的被等待线程唤醒的线程。如果多个线程在等待同一个对象的锁,但只有一个线程会被唤醒,而其他线程将继续等待。这意味着,如果多个线程在等待同一个对象的锁,并且其中一个线程已经持有该对象的锁并调用notify()方法,只有一个线程会被唤醒,而其他线程将继续等待。

下面是一些基本的Java代码,演示了notify()方法在多线程编程中的使用:

class ThreadA extends Thread {
    private Object lock;

    public ThreadA(Object lock) {
        this.lock = lock;
    }

    public void run() {
        synchronized (lock) {
            System.out.println("ThreadA start");
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("ThreadA end");
        }
    }
}

class ThreadB extends Thread {
    private Object lock;

    public ThreadB(Object lock) {
        this.lock = lock;
    }

    public void run() {
        synchronized (lock) {
            System.out.println("ThreadB start");
            lock.notify();
            System.out.println("ThreadB end");
        }
    }
}

public class Example {
    public static void main(String[] args) {
        Object lock = new Object();
        ThreadA threadA = new ThreadA(lock);
        ThreadB threadB = new ThreadB(lock);
        threadA.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadB.start();
    }
}

在这个例子中,我们创建了两个线程,ThreadA和ThreadB。ThreadA会在lock对象上等待,ThreadB会唤醒ThreadA。当ThreadA被唤醒时,它调用System.out.println()打印一条消息,然后结束。

notifyAll()

notifyAll()方法将唤醒所有在等待对象锁的线程。如果多个线程在等待同一个对象的锁,并且其中一个线程已经持有该对象的锁,并调用notifyAll()方法,所有等待线程都会被唤醒。

notifyAll()方法在多线程编程中的使用和notify()方法非常相似。下面是一个基本的Java代码示例:

class WaitNotify {
    void doWait() {
        synchronized (this) {
            System.out.println("Before wait");
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("After wait");
        }
    }

    void doNotify() {
        synchronized (this) {
            System.out.println("Before notifyAll");
            notifyAll();
            System.out.println("After notifyAll");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        WaitNotify waitNotify = new WaitNotify();
        Runnable runnable = () -> waitNotify.doWait();
        Runnable runnable1 = () -> waitNotify.doWait();
        Thread thread = new Thread(runnable);
        Thread thread1 = new Thread(runnable1);
        thread.start();
        thread1.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        waitNotify.doNotify();
    }
}

在这个例子中,我们创建了两个线程,它们都会在WaitNotify对象上等待。当WaitNotify调用doNotify()方法时,所有等待线程都会被唤醒。每个线程都调用System.out.println()打印一条消息,然后结束。

总结

notify()方法只能唤醒等待对象锁的单个线程,而notifyAll()方法将唤醒所有等待对象锁的线程。在多线程编程中,notifyAll()方法通常比notify()方法更常用,因为它可以确保所有等待线程都被唤醒,这可以防止线程死锁或永久等待。然而,如果只想唤醒一个线程,notify()方法可能更加适合。