Java实现生产者消费者的方式有:wait && notify、BlockingQueue、Lock && Condition等

wait、notify注意事项:
(1)可以使用wait()和notify()方法在Java中实现线程间通信。不只是一个或两个线程,而是多个线程可以使用这些方法相互通信。
(2)在synchronized方法或synchronized块中调用wait(),notify()和notifyAll()方法,否则JVM将抛出IllegalMonitorStateException。
(3)从while(条件)循环调用wait和notify方法,而不是从if()块调用,因为要重复检查条件,而不仅仅是一次。
(4)多使用notifyAll方法而不是notify。

下面是wait、notify等待通知实现的生产者-消费者模式:
生产者:

/**
* 生产者
*
* @author monkjavaer
* @date 2018/12/15 11:13
*/
public class Producer implements Runnable {
/**
* 产品容器
*/
private final List<Integer> container; public Producer(List<Integer> container) {
this.container = container;
} /**
* 生产者生产方法
*
* @throws InterruptedException
*/
private void produce() throws InterruptedException {
//产品容器容量
int capacity = 5;
synchronized (container) {
//当容器已满,暂停生产
while (container.size() == capacity) {
System.out.println("...容器已经满了,暂停生产...");
container.wait();
}
Random random = new Random();
int p = random.nextInt(50);
//模拟1秒生产一个产品
TimeUnit.MILLISECONDS.sleep(1000);
System.out.println("生产产品:" + p);
container.add(p);
container.notifyAll();
}
} @Override
public void run() {
while (true) {
try {
produce();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("produce error");
}
}
}
}

  消费者:

/**
* 消费者
* @author monkjavaer
* @date 2018/12/15 11:13
*/
public class Consumer implements Runnable{ /**
* 产品容器
*/
private final List<Integer> container; public Consumer(List<Integer> container) {
this.container = container;
} /**
* 消费者消费产品
*/
private void consume() throws InterruptedException {
synchronized (container){
while (container.isEmpty()){
System.out.println("...容器是空的,暂停消费...");
container.wait();
}
Integer p = container.remove(0);
//模拟1秒消费一个产品
TimeUnit.MILLISECONDS.sleep(1000);
System.out.println("消费产品:" + p);
container.notifyAll();
}
}
@Override
public void run() {
while (true){
try {
consume();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("consume error");
}
}
}
}

  测试:

public class ProducerConsumerTest {
public static void main(String[] args) {
List<Integer> container = new ArrayList<>();
Thread producer = new Thread(new Producer(container));
Thread consumer = new Thread(new Consumer(container));
producer.start();
consumer.start();
}
}

  输出:

生产产品:14
生产产品:17
消费产品:14
生产产品:0
生产产品:39
生产产品:4
生产产品:3
...容器已经满了,暂停生产...
消费产品:17
消费产品:0
消费产品:39
消费产品:4
消费产品:3
...容器是空的,暂停消费...
生产产品:25
生产产品:33
生产产品:17
消费产品:25
消费产品:33
消费产品:17
...容器是空的,暂停消费...

  

wait、notify应用场景(生产者-消费者模式)的更多相关文章

  1. java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现

    java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了  wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...

  2. 10 阻塞队列 & 生产者-消费者模式

    原文:http://www.cnblogs.com/dolphin0520/p/3932906.html 在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(Li ...

  3. java 多线程并发系列之 生产者消费者模式的两种实现

    在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...

  4. Handler机制与生产者消费者模式

    本文梳理了 Handler 的源码,并详细阐述了 Handler 与生产者消费者模式的关系,最后给出了多版自定义 Handler 实现.本文首发于简书,重新整理发布. 一.Handler Handle ...

  5. java多线程 生产者消费者模式

    package de.bvb; /** * 生产者消费者模式 * 通过 wait() 和 notify() 通信方法实现 * */ public class Test1 { public static ...

  6. 转:Task任务调度实现生产者消费者模式

    我们经常会遇到生产者消费者模式,比如前端各种UI操作事件触发后台逻辑等.在这种典型的应用场景中,我们可能会有4个业务处理逻辑(下文以P代表生产者,C代表消费者): 1. FIFO(先进先出)      ...

  7. 使用BlockingQueue的生产者消费者模式

    BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.使用场景. 首先它是一个队列,而一个队 ...

  8. Java设计模式—生产者消费者模式(阻塞队列实现)

    生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...

  9. 【多线程】--生产者消费者模式--Lock版本

    在JDK1.5发布后,提供了Synchronized的更优解决方案:Lock 和 Condition 我们使用这些新知识,来改进例子:[多线程]--生产者消费者模式--Synchronized版本 改 ...

随机推荐

  1. 【知识总结】多项式全家桶(三)(任意模数NTT)

    经过两个月的咕咕,"多项式全家桶" 系列终于迎来了第三期--(雾) 上一篇:[知识总结]多项式全家桶(二)(ln和exp) 先膜拜(伏地膜)大恐龙的博客:任意模数 NTT (在页面 ...

  2. Spring加载applicationContext.xml实现spring容器管理的单例模式

    package com.etc.pojo; import org.springframework.context.ApplicationContext; import org.springframew ...

  3. 279 Perfect Squares 完美平方数

    给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...) 使得他们的和等于 n.你需要让平方数的个数最少.比如 n = 12,返回 3 ,因为 12 = 4 + 4 + 4 : ...

  4. 冒泡 [Python]

    冒泡Python class BubbleSort: def __init__(self): self.initArr() def initArr(self): self.arrInfo = [60, ...

  5. 微信关于网页授权access_token和普通access_token的区别

    微信官网网址:https://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html#.E9.99.84.EF.BC.9A.E6. ...

  6. Python+selenium学习(一) 打开Firefox浏览器,IE浏览器和Chrome浏览器

    from selenium import webdriver # open Firefox #driver=webdriver.Firefox() # Open IE #driver=webdrive ...

  7. Hive DDL&DML

    1.删除分区 ALTER TABLE table_name DROP IF EXISTS PARTITION(dt=') 如果是外部表,记得rm对应文件 2.添加分区 ALTER TABLE tabl ...

  8. ansible 批量推送ssh秘钥

    ansible 批量推送ssh秘钥 参考:http://docs.ansible.com/ansible/authorized_key_module.html # vi /etc/ansible/ho ...

  9. Computed Properties vs Property Requirements - protocol

    In addition to stored properties, classes, structures, and enumerations can define computed properti ...

  10. 第三节:EF

    1.删除要进行判空 public ActionResult DelClassMethod(string gId) { //根据gId查询对应条目 var grade = oc.BllSession.I ...