Java 学习笔记 使用synchronized实现生产者消费者模式
说明
- Object.wait()使当前的线程进入到等待状态(进入到等待队列)
- Object.notifyAll() 唤醒等待中的全部线程
- Object.notify() 随机唤醒一个线程
代码
consumer.java
public class Consumer extends Thread {
List<Object> container;
/*表示当前线程共生产了多少件物品*/
private int count;
public Consumer(String name, List<Object> container) {
super(name);
this.container = container;
}
@Override
public void run() {
while(true){
synchronized (container) {
try {
if (container.isEmpty()) { //仓库已空,不能消 只能等
container.wait(20);
} else {
// 消费
container.remove(0);
this.count++;
System.out.println("消费者:" + getName() + " 共消费了:" + this.count + "件物品,当前仓库里还有" + container.size() + "件物品");
container.notifyAll(); // 唤醒等待队列中所有线程
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Producer.java
public class Producer extends Thread{
List<Object> container;
/*表示当前线程共生产了多少件物品*/
private int count;
public Producer(String name, List<Object> container) {
super(name);
this.container = container;
}
@Override
public void run() {
while (true) {
synchronized (container) {
try {
// 如果某一个生产者能执行进来,说明此线程具有container对象的控制权,其它线程(生产者&消费者)都必须等待
if (container.size() == 10) { // 假设container最多只能放10个物品,即仓库已满
container.wait(10); //表示当前线程需要在container上进行等待
} else {
// 仓库没满,可以放物品
container.add(new Object());
this.count++;
System.out.println("生产者:" + getName() + " 共生产了:" + this.count + "件物品,当前仓库里还有" + container.size() + "件物品");
// 生产者生产了物品后应通知(唤醒)所有在container上进行等待的线程(生产者&消费者)
// 生:5, 消:5
// container.notify(); // 随机唤醒一个在等待队列中的线程
container.notifyAll(); // 唤醒等待队列中所有线程
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} //
try {
sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Test.java
public class Test {
public static void main(String[] args) {
// 仓库
List<Object> container = new ArrayList<>();
new Producer("老王", container).start();
new Consumer("小芳", container).start();
new Producer("老李", container).start();
new Consumer("小荷", container).start();
new Producer("老张", container).start();
new Consumer("小花", container).start();
new Producer("老刘", container).start();
new Consumer("小妞", container).start();
new Consumer("小米", container).start();
new Producer("老马", container).start();
}
}
Java 学习笔记 使用synchronized实现生产者消费者模式的更多相关文章
- Java Thread系列(十)生产者消费者模式
Java Thread系列(十)生产者消费者模式 生产者消费者问题(producer-consumer problem),是一个多线程同步问题的经典案例.该问题描述了两个共亨固定大小缓冲区的线程-即所 ...
- java ReentrantLock结合条件队列 实现生产者-消费者模式 以及ReentratLock和Synchronized对比
package reentrantlock; import java.util.ArrayList; public class ProviderAndConsumerTest { static Pro ...
- python 多线程笔记(6)-- 生产者/消费者模式(续)
用 threading.Event() 也可以实现生产者/消费者模式 (自己拍脑袋想出来的,无法知道其正确性,请大神告知为谢!) import threading import time import ...
- Java的设计模式(7)— 生产者-消费者模式
生产者-消费者模式是一个经典的多线程设计模式,它为多线程间的协作提供了良好的解决方案.这个模式中,通常有两类线程,即若干个生产者线程和若干个消费者线程.生产者线程负责提交用户请求,消费者线程则负责具体 ...
- python 多线程笔记(5)-- 生产者/消费者模式
我们已经知道,对公共资源进行互斥访问,可以使用Lock上锁,或者使用RLock去重入锁. 但是这些都只是方便于处理简单的同步现象,我们甚至还不能很合理的去解决使用Lock锁带来的死锁问题. 要解决更复 ...
- Java笔记1 : 在生产者消费者模式中,线程通信与共享数据,死锁问题与解决办法
本例定义了4个类,这里说一下,方便下面讲解.分别是Product(产品),Producer(生产者),Consumer(消费者), Test(测试类). 多线程之间通信与共享数据只要引用同一内存区域就 ...
- 2.3多线程(java学习笔记)synchronized关键字
一.为什么要用synchronized关键字 首先多线程中多个线程运行面临共享数据同步的问题. 多线程正常使用共享数据时需要经过以下步骤: 1.线程A从共享数据区中复制出数据副本,然后处理. 2.线程 ...
- Java 学习笔记之 Synchronized锁重入
Synchronized锁重入: 当一个线程得到一个对象锁后,再次请求此对象锁时是可以再次得到该对象的锁.这也证明在一个Synchronized方法/块的内部调用本类的其他Synchronized方法 ...
- Java 学习笔记之 Synchronized锁对象
Synchronized锁对象: Synchronized取得的锁都是对象锁,而不是把一段代码或方法当作锁,哪个线程执行带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁,那么其 ...
随机推荐
- Json----简单介绍
Json 先分享一个网站http://www.bejson.com/,这个是用来检测Json文件的错误的,Json文件一般不好查找错误. 看懂Json只需要四句话: 对象表示为键值对 数据由逗号分隔 ...
- Fragment中TabLayout加FragmentViewPager
让tablayout中的Tab平铺:在tablayout布局中写: app:tabMaxWidth="0dp"app:tabGravity="fill"app: ...
- NumPy库实现矩阵计算
随着机器学习技术越来越向着整个社会进行推广,因此学好线性代数和Python当中的numpy库就相当重要了.我们应该知道numpy库的使用是sklearn库和opencv库的基础.主要用于矩阵的计算.当 ...
- [Swift]LeetCode167. 两数之和 II - 输入有序数组 | Two Sum II - Input array is sorted
Given an array of integers that is already sorted in ascending order, find two numbers such that the ...
- [Swift]LeetCode348. 设计井字棋游戏 $ Design Tic-Tac-Toe
Design a Tic-tac-toe game that is played between two players on a n x n grid. You may assume the fol ...
- [Swift]LeetCode653. 两数之和 IV - 输入 BST | Two Sum IV - Input is a BST
Given a Binary Search Tree and a target number, return true if there exist two elements in the BST s ...
- 什么是REST接口
转载自:http://baijiahao.baidu.com/s?id=1591007540303121112&wfr=spider&for=pc 从事web开发工作有一小段时间,RE ...
- Java常用工具类练习题
1.请根据控制台输入的特定日期格式拆分日期 如:请输入一个日期(格式如:**月**日****年) 经过处理得到:****年**月**日 提示:使用String的方法indexOf.lastIndexO ...
- VIVO 手机重力传感器踩坑记录
手上的 vivo-x9 手机传感器模式下的旋转效果有误,经查发现是 Gravity sensor 返回的数据有误,和其他机型返回的数据相反的. 参考 Gravity 的说明: A three dime ...
- Python——day12 nonlcoal关键字、装饰器(开放封闭原则、函数被装饰、最终写法)
一.nonlocal关键字 1.作用:将L与E(E中的名字需要提前定义)的名字统一 2.应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值 def outer(): num=10 print ...