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关键字的方法,哪个线程就持有该方法所属对象的锁,那么其 ...
随机推荐
- JPG、PNG、GIF、SVG 等格式图片区别
1.图片 2. 前言 首先,我们要清楚的是,图片从类型上分,可以分为 位图 和 矢量图. 位图:位图又叫点阵图或像素图,计算机屏幕上的图是由屏幕上的发光点(即像素)构成的,每个点用二进制数据来描述其颜 ...
- Vue 项目: npm run dev 报错 webpack-dev-server
从码云上下载vue项目,运行npm run dev 时报错: > webpack-dev-server --inline --progress --config build/webpack.de ...
- Android Studio 去除上方标题
选中代码再Ctrl+shift+'/' 可加/***/注释 https://blog.csdn.net/wuqingsen1/article/details/78554117 styles.xml & ...
- 问题:win7下配置好服务器就是不能查询数据库。(已解决)
我用C写访问mysql的CGI程序,可以执行. 但是,当我写好网页再去访问这个CGI,出现下面的错误 我的环境是:IIS作为服务器,MYSQL数据库,VC++6.0写CGI. 跟踪了一下,发现只要我调 ...
- Spring Cloud 微服务架构全链路实践
阅读目录: 1. 网关请求流程 2. Eureka 服务治理 3. Config 配置中心 4. Hystrix 监控 5. 服务调用链路 6. ELK 日志链路 7. 统一格式返回 Java 微服务 ...
- [Swift]LeetCode323. 无向图中的连通区域的个数 $ Number of Connected Components in an Undirected Graph
Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...
- [Swift]LeetCode503. 下一个更大元素 II | Next Greater Element II
Given a circular array (the next element of the last element is the first element of the array), pri ...
- [Swift]LeetCode950. 按递增顺序显示卡牌 | Reveal Cards In Increasing Order
In a deck of cards, every card has a unique integer. You can order the deck in any order you want. ...
- Linux 虚拟网络设备详解之 Bridge 网桥
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 前面几篇文章介 ...
- iOS学习——核心动画之Layer基础
iOS学习——核心动画之Layer基础 1.CALayer是什么? CALayer我们又称它叫做层.在每个UIView内部都有一个layer这样一个属性,UIView之所以能够显示,就是因为它里面有这 ...