在Java中,notify()和wait()是用于线程间通信的方法。当一个线程调用对象的wait()方法时,该线程会被挂起,直到另一个线程调用该对象的notify()方法为止。下面是一个通俗易懂的例子:假设有一个面包店,有一个生产者线程和一个消费者线程。生产者线程负责生产面包,消费者线程负责消费面包。当面包库存为空时,消费者线程会进入等待状态,等待生产者线程生产面包并通知它。当生产者线程生产了面包后,会调用notify()方法通知消费者线程,消费者线程收到通知后会重新进入运行状态并消费面包。
public class BreadShop {
private int breadCount = 0;
public synchronized void produce() {
while (breadCount >= 10) {
try {
wait(); // 库存已满,生产者线程进入等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
breadCount++;
System.out.println("生产了1个面包,当前库存为:" + breadCount);
notify(); // 生产完成,通知消费者线程
}
public synchronized void consume() {
while (breadCount <= 0) {
try {
wait(); // 库存为空,消费者线程进入等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
breadCount--;
System.out.println("消费了1个面包,当前库存为:" + breadCount);
notify(); // 消费完成,通知生产者线程
}
}
public class Consumer implements Runnable {
private BreadShop breadShop;
public Consumer(BreadShop breadShop) {
this.breadShop = breadShop;
}
@Override
public void run() {
while (true) {
breadShop.consume();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Producer implements Runnable {
private BreadShop breadShop;
public Producer(BreadShop breadShop) {
this.breadShop = breadShop;
}
@Override
public void run() {
while (true) {
breadShop.produce();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) {
BreadShop breadShop = new BreadShop();
new Thread(new Producer(breadShop)).start();
new Thread(new Consumer(breadShop)).start();
}
}
另外一个例子
public class Message {
private String content;
private boolean available = false;
public synchronized String getContent() {
while (!available) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
available = false;
notifyAll();
return content;
}
public synchronized void setContent(String content) {
while (available) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.content = content;
available = true;
notifyAll();
}
}
public class Consumer implements Runnable {
private Message message;
public Consumer(Message message) {
this.message = message;
}
public void run() {
String message;
while (!(message = this.message.getContent()).equals("exit")) {
System.out.println("Consumed " + message);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Producer implements Runnable {
private Message message;
public Producer(Message message) {
this.message = message;
}
public void run() {
String[] messages = {"Message 1", "Message 2", "Message 3", "Message 4"};
for (String message : messages) {
this.message.setContent(message);
System.out.println("Produced " + message);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.message.setContent("exit");
}
}
public class ThreadCommunication {
public static void main(String[] args) {
Message message = new Message();
new Thread(new Producer(message)).start();
new Thread(new Consumer(message)).start();
}
}