Java多线程通信wait()和notify()代码实例
目录
介绍
在Java多线程编程中,多个线程之间需要进行通信,来实现协作完成任务。Java提供了一种机制,即wait()和notify()方法,用于实现多线程之间的通信。
wait()方法和notify()方法
wait()和notify()方法属于Object类,可以用于实现线程之间的通信。其中,wait()方法是使当前执行的线程进入等待状态(阻塞),知道其他线程调用notify()或notifyAll()方法唤醒该线程为止。而notify()方法则是唤醒等待中的线程。
wait()方法和notify()方法必须在同步块或同步方法中调用,并且必须针对同一对象进行调用,否则会抛出IllegalMonitorStateException异常。
wait()和notify()方法的用法
wait()方法和notify()方法一般是配合使用,以实现一些特定的多线程编程模型。一般的使用方式如下:
synchronized(obj) {
while(条件不满足) {
obj.wait(); // 线程阻塞
}
// 执行响应的操作
// ...
// 操作完成后,唤醒其他线程
obj.notifyAll();
}
wait()方法主要用于等待条件,等待其他线程对此对象发出notify()或notifyAll()方法的调用,使得该线程退出等待状态。
示例说明
示例1:打印奇偶数
我们可以用wait()和notify()方法来实现一个简单的多线程任务,即循环打印从1到100的数字,其中偶数由一个线程打印,奇数由另一个线程打印。具体代码如下:
public class Main {
public static void main(String[] args) {
Object obj = new Object();
Thread t1 = new Thread(new Printer(obj, true)); // 打印奇数的线程
Thread t2 = new Thread(new Printer(obj, false)); // 打印偶数的线程
t1.start();
t2.start();
}
}
class Printer implements Runnable {
private boolean isOdd; // 是否打印奇数
private Object obj;
private int i = 1;
public Printer(Object obj, boolean isOdd) {
this.obj = obj;
this.isOdd = isOdd;
}
public void run() {
while(i <= 100) {
synchronized(obj) {
while((i % 2 == 0) == isOdd) {
try {
obj.wait(); // 等待
} catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ": " + i);
i++;
obj.notifyAll(); // 唤醒其他线程
}
}
}
}
在以上代码中,我们创建了一个Printer线程类,该线程类的作用是从1到100依次打印出来,一个线程负责打印奇数,另一个线程负责打印偶数。该线程类的run()方法中使用了wait()和notify()实现了线程之间的同步,确保奇数和偶数依次打印。
示例2:生产者和消费者模型
生产者和消费者模型是指一个线程负责生产数据,另一个线程负责消费数据的一种模型。我们可以用wait()和notify()方法来实现生产者和消费者模型,具体代码如下:
public class Main {
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
Object lock = new Object();
Thread producer = new Thread(new Producer(queue, lock));
Thread consumer = new Thread(new Consumer(queue, lock));
producer.start();
consumer.start();
}
}
class Producer implements Runnable {
private Queue<Integer> queue;
private Object lock;
public Producer(Queue<Integer> queue, Object lock) {
this.queue = queue;
this.lock = lock;
}
public void run() {
while(true) {
int num = (int)(Math.random() * 100);
synchronized(lock) {
while(queue.size() >= 10) { // 如果队列已满,等待
try {
lock.wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
queue.offer(num);
System.out.println(Thread.currentThread().getName() + " 生产: " + num);
lock.notifyAll(); // 唤醒其他线程
}
}
}
}
class Consumer implements Runnable {
private Queue<Integer> queue;
private Object lock;
public Consumer(Queue<Integer> queue, Object lock) {
this.queue = queue;
this.lock = lock;
}
public void run() {
while(true) {
synchronized(lock) {
while(queue.isEmpty()) { // 如果队列为空,等待
try {
lock.wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
int num = queue.poll();
System.out.println(Thread.currentThread().getName() + " 消费: " + num);
lock.notifyAll(); // 唤醒其他线程
}
}
}
}
在以上代码中,我们创建了Producer和Consumer两个线程类,分别负责生产和消费数据。在Producer线程的run()方法中,我们使用了while循环,不停地生产数据,并使用wait()和notify()方法实现线程之间的同步,确保在队列已满的情况下等待,如果队列不满,就将数据添加到队列中。在Consumer线程的run()方法中,也是用while循环不断地消费数据,并使用wait()和notify()方法实现线程之间的同步,确保在队列为空的情况下等待,如果队列不为空,就从队列中取出数据并消费。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程通信wait()和notify()代码实例 - Python技术站