📅  最后修改于: 2023-12-03 15:31:36.473000             🧑  作者: Mango
在Java中,一个线程可以通过等待来等待另一个线程发出通知。当线程等待时,它进入睡眠状态,并释放其持有的锁。当它被通知时,它会醒来并重新请求锁。Java提供了两种方法来通知等待中的线程:notify()和notifyAll()。
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()方法在多线程编程中的使用和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()方法可能更加适合。