您的位置:首页 > 编程语言 > Java开发

JAVA线程同步——消费者和生产者模式

2016-03-27 13:42 423 查看

场景介绍

我们有一个数据缓冲区,一个或者多个生产者把数据存入这个缓冲区,一个或者多个消费者从缓冲区中取出数据
缓冲区中的是共享数据
当缓冲区满的时候不能生产者将不能再放入数据到缓冲区(生产者线程阻塞)
当缓冲区空的时候消费者不能从缓冲区中读取数据(消费者线程阻塞)

实例:
1. 创建数据处理类,其中缓冲区的保存、读取、生产操作
public class EventStorage {

//缓冲区数据的最大值
private int maxSize;
//缓冲区
private List<Date> storage;

public EventStorage() {
maxSize = 10;
storage = new LinkedList<>();
}

//生产方法
public synchronized void set() {
//如果已满就挂起线程
while (storage.size() == maxSize) {
try {
System.out.println("producer wait");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
storage.add(new Date());
System.out.println("Set : " + storage.size());
//通知等待的线程消费者线程
notifyAll();
}

//消费方法
public synchronized void get() {
//如果没有库存就挂起线程
while (storage.size() == 0) {
try {
System.out.println("consumer wait");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
((LinkedList<?>) storage).poll();
System.out.println("Get : " + storage.size());
//通知阻塞的线程生产者线程
notifyAll();
}

}

2. 创建生产者线程,其构造函数接收一个数据处理对象

public class EventProducer implements Runnable {

private EventStorage storage;

public EventProducer(EventStorage storage) {
this.storage = storage;
}

@Override
public void run() {
for (int i = 0; i < 100; i++) {
storage.set();
}
}

}

3.创建消费者线程,也接收同一个数据处理对象
public class EventConsumer implements Runnable {

private EventStorage storage;

public EventConsumer(EventStorage storage) {
this.storage = storage;
}

@Override
public void run() {
for (int i = 0; i < 100; i++) {
storage.get();
}
}

}

4.创建测试类
public class TestCP {

public static void main(String[] args) {
EventStorage storage = new EventStorage();

Thread consumer = new Thread(new EventConsumer(storage));
Thread producer = new Thread(new EventProducer(storage));

consumer.start();
producer.start();

}

}

5.运行程序查看控制台输出

可以看到程序输出和预期的结果一样

注意:
1.必须在while()循环内调用wait(),使得线程在达到指定条件后跳出循环等待才继续运行
2.数据处理类的生产和消费方法是synchronized修饰的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息