接下来我将为大家详细讲解“Java多线程中的wait/notify通信模式实例详解”。
一、前言
在Java多线程编程中,线程间通信是一项重要的技术。wait/notify通信模式是一种应用广泛的线程间通信方法。通过wait/notify通信模式,线程能够在不使用轮询的情况下进行线程间的信息传递和共享,提高了线程间的运行效率,降低了系统资源的消耗。
本篇攻略将为大家介绍Java多线程中的wait/notify通信模式的实例详解。通过两个示例,将带领大家深入了解wait/notify通信模式的使用方法和注意事项。
二、示例一:生产者/消费者模式
生产者/消费者模式是多线程编程中一个非常常见的模式。在该模式中,生产者线程负责生产数据,消费者线程负责消费数据。生产者线程将数据生产出来后,需要将数据传递给消费者线程,消费者线程等待生产者线程生产数据,然后再进行消费。在该模式中,就需要用到wait/notify通信模式。
以下是实现生产者/消费者模式的方法:
- 定义一个共享数据的缓冲区,该缓冲区可以存放多个数据。
- 定义一个生产者线程,该线程负责生产数据,并将数据放入共享数据缓冲区中。
- 定义一个消费者线程,该线程负责从共享数据缓冲区中取数据,并进行消费。
- 在生产者线程中,使用synchronized关键字对共享数据缓冲区进行加锁。
- 在生产者线程中,当共享数据缓冲区中的数据满了时,使用wait方法等待。
- 在生产者线程中,当共享数据缓冲区有空位时,使用notify方法通知消费者线程可以取数据了。
- 在消费者线程中,使用synchronized关键字对共享数据缓冲区进行加锁。
- 在消费者线程中,当共享数据缓冲区中没有数据时,使用wait方法等待。
- 在消费者线程中,当共享数据缓冲区有数据时,使用notify方法通知生产者线程可以生产数据了。
以下是示例代码:
public class ProducerConsumerDemo {
public static void main(String[] args) {
Buffer buffer = new Buffer();
new Thread(new Producer(buffer)).start();
new Thread(new Consumer(buffer)).start();
}
}
class Buffer {
private int[] data = new int[10];
private int count = 0;
public synchronized void put(int num) {
if (count == data.length) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
data[count] = num;
count++;
notify();
}
public synchronized int get() {
if (count == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
int num = data[count];
notify();
return num;
}
}
class Producer implements Runnable {
private Buffer buffer;
public Producer(Buffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
buffer.put(i);
System.out.println("生产者生产了:" + i);
try {
Thread.sleep((int) (Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
private Buffer buffer;
public Consumer(Buffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
int num = buffer.get();
System.out.println("消费者消费了:" + num);
try {
Thread.sleep((int) (Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
在该示例中,我们定义了一个Buffer类作为共享数据的缓冲区,使用synchronized关键字对该类进行加锁,保证了线程安全。生产者线程使用wait方法等待共享数据缓冲区有空位,使用notify方法通知消费者线程可以取数据了。消费者线程使用wait方法等待共享数据缓冲区有数据,使用notify方法通知生产者线程可以生产数据了。在运行该示例时,可以看到生产者线程和消费者线程交替运行,保证了线程的正确性。
三、示例二:实现线程顺序执行
在Java多线程编程中,线程的运行顺序是随机的,我们无法直接控制线程的运行顺序。但是使用wait/notify通信模式,我们可以实现线程的顺序执行。
以下是实现线程顺序执行的方法:
- 定义多个线程,每个线程都需要有自己的标识符。
- 在每个线程中,使用synchronized关键字对共享对象进行加锁。
- 在每个线程中,使用while循环进行判断,当标识符不等于自己时,使用wait方法等待。
- 当线程执行完毕后,改变标识符并使用notifyAll方法通知其他线程执行。
以下是示例代码:
public class ThreadSequenceDemo {
public static void main(String[] args) {
Object lock = new Object();
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.length; i++) {
threads[i] = new SequenceThread(lock, i);
threads[i].start();
}
}
}
class SequenceThread extends Thread {
private Object lock;
private int id;
public SequenceThread(Object lock, int id) {
this.lock = lock;
this.id = id;
}
@Override
public void run() {
synchronized (lock) {
while (id != Sequence.order) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread " + id + " is running.");
Sequence.order++;
lock.notifyAll();
}
}
}
class Sequence {
public static int order = 0;
}
在该示例中,我们定义了一个SequenceThread类作为线程的实现类,使用synchronized关键字对共享对象进行加锁,保证线程安全。在每个线程中,使用while循环进行判断当前线程的标识符是否等于Sequence.order顺序,如果不等于,则使用wait方法等待。当线程执行完毕后,改变Sequence.order标识符并使用notifyAll方法通知其他线程执行。
以上就是本文对“Java多线程中的wait/notify通信模式实例详解”的介绍,希望本文能够对大家有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程中的wait/notify通信模式实例详解 - Python技术站