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修饰的
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树