java多线程 生产者和消费者 lock
package com.atguigu.thread.lock; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /*
* 小米厂家:
* 库房有限,只能存10台小米电视
* 工人的生产电视与销售的卖电视同时进行
* 当工人生产电视把库房存满了,要求工人休息,直到销售卖出至少一台电视,库房可以再次电视,然后他再次开始生产
* 当销售者把库房的电视都卖完了,要求销售者休息,直到工人生产了至少一台电视,销售才继续卖电视
*
* 工人是一个线程
* 销售是一个线程
*
* 需要线程的通信:当工人休息后,销售组销售了电视,应该告知工人一声,可以继续生产了
* 当销售休息后,工人如果生产了电视,应该通知销售,可以开始卖电视了
*
* 问题:
* (1)因为共享num变量,所以有线程安全问题:依靠同步解决
* (2)因为库房有限:线程通信 wait,notify
*
* 涉及到的方法:
* (1)wait:等待
* (2)notify/notifyAll:通知
*
* 这两个方法必须由“锁”对象来调用
* “锁”对象,必须是多个线程共享的锁对象
*
* 如果是多个工人,多个销售者
*
* synchronized:隐式锁
* wait
* notify/notifyAll
*
* 如果使用Lock锁,那么线程通信应该使用Condition来解决通信
* 条件.await():某种条件,等待
* 条件.signal():某种条件唤醒
*
*/
public class TestTongXin { public static void main(String[] args) {
Houseware h = new Houseware(); Worker w1 = new Worker(h);
Worker w2 = new Worker(h);
Saler s1 = new Saler(h);
Saler s2 = new Saler(h); w1.start();
w2.start();
s1.start();
s2.start();
} }
class Houseware{
private static final int MAX_VALUE = 10;
private int num = 0;
private Lock lock = new ReentrantLock();
private Condition full = lock.newCondition();
private Condition empty = lock.newCondition(); //往里放电视
public void add(){
lock.lock();
if(num>=MAX_VALUE){
try {
full.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
num++;
try {
Thread.sleep(100);//为了问题暴露的明显一点
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("工人生产了一台电视,现在库存是:" + num);
// empty.signal();
empty.signalAll();
} lock.unlock();
} //往外拿电视
public void take(){
lock.lock();
if(num<=0){
try {
empty.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
num--;
try {
Thread.sleep(100);//为了问题暴露的明显一点
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("销售卖了一台电视,现在库存是:" + num);
full.signalAll();
} lock.unlock();
}
} class Worker extends Thread{
private Houseware h; public Worker(Houseware h) {
super();
this.h = h;
} public void run(){
//往仓库放电视
// 库房.add();
while(true){
h.add();
}
}
}
class Saler extends Thread{
private Houseware h; public Saler(Houseware h) {
super();
this.h = h;
} public void run(){
while(true){
h.take();
}
}
}
java多线程 生产者和消费者 lock的更多相关文章
- Java 多线程-生产者、消费者
一.整体代码 ThreadDemo.java public class ThreadDemo { public static void main(String[] args) { Godown god ...
- JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题
JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序猿杜鹏程的博客:http://blog ...
- Windows下RabbitMQ 的下载、配置、Java实现生产者和消费者例子
RabbitMQ是一个轻量级的消息代理中间件,支持多种消息通信协议,支持分布式部署,支持运行于多个操作系统,具有灵活.高可用等特性.RabbitMQ支持多种协议,其中最为重要的是高级消息队列协议(AM ...
- java实现生产者和消费者问题
Java实现生产者和消费者问题 欢迎访问我的个人博客,获取更多有用的东西 链接一 链接二 也可以关注我的微信订阅号:CN丶Moti
- Java中生产者与消费者模式
生产者消费者模式 首先来了解什么是生产者消费者模式.该模式也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例.该问题描述了两个共享固定大小缓冲区的线 ...
- Java实现生产者和消费者
生产者和消费者问题是操作系统的经典问题,在实际工作中也常会用到,主要的难点在于协调生产者和消费者,因为生产者的个数和消费者的个数不确定,而生产者的生成速度与消费者的消费速度也不一样,同时还要实现生产者 ...
- python多线程+生产者和消费者模型+queue使用
多线程简介 多线程:在一个进程内部,要同时干很多事情,就需要同时执行多个子任务,我们把进程内的这些子任务叫线程. 线程的内存空间是共享的,每个线程都共享同一个进程的资源 模块: 1._thread模块 ...
- java之生产者与消费者
package com.produce; import java.util.LinkedList; import java.util.Queue; /*@author shijin * 生产者与消费者 ...
- java线 生产者和消费者
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlhbmdydWkxOTg4/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
随机推荐
- vue 路由嵌套高亮问题
正常路由嵌套是没有问题的,但是如果你已经在当前主路由页面了,然后再次点击主路由就会出现页面数据空白的情况 看代码: //主路由通过v-for循环出来 <div class="list- ...
- AXIS2整合spring需要的jar,以及大部分缺少jar所报的异常
axis2 webservice 服务端jar包: -->axis2-kernel-1.6.1.jar -->axis2-spri ...
- PAT1132: Cut Integer
1132. Cut Integer (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Cutting a ...
- virsh命令来创建虚拟机
virsh命令来创建虚拟机步骤 (1)生成硬盘镜像文件: 格式:raw或qcow2 # qemu-img create -f raw fdisk.img 10G qemu-img convert re ...
- 关于Linux虚拟化技术KVM的科普 科普四(From humjb_1983)
另一组关于KVM的分析文档,虚拟化相关概念.KVM基本原理和架构一-概念和术语.KVM基本原理和架构二-基本原理.KVM基本原理及架构三-CPU虚拟化.KVM基本原理及架构四-内存虚拟化.KVM基本原 ...
- 解决BackBox中Fcitx输入法中文输入状态下不显示候选词框的问题
当我们安装Fcitx输入法时默认是安装了下面这个组件的: fcitx-module-kimpanel 该组件在非KDE桌面环境下可能会使Fcitx输入法在输入中文时无法显示候选词框. 使用下面的命令移 ...
- binlog——逻辑复制的基础
Ⅰ.binlog定义和作用 1.1 定义 记录每次数据库的逻辑操作(包括表结构变更和表数据修改) 包含:binlog文件和index文件 1.2 作用 复制:从库读取主库binlog,本地回放实现复制 ...
- BootStrap 专题
验证码的输入框和验证码图片在一行,用bootstrap原生的怎么写呢? 看了教程,没有完全一样的可以让右侧的按钮“输入验证码”固定大小.左侧的输入框动态大小吗? <div class=&qu ...
- sql server 高可用故障转移(6)
创建分布式事务处理DTC群集服务 在hsr3 ip 49上继续 \ 输入一个没有冲突的ip地址用作SQL-CL的DTC解析地址:192.168.2.110,通过检测后会在DNS服务器中自动创建一条记录 ...
- Python中使用MongoEngine1
pymongo来操作MongoDB数据库,但是直接把对于数据库的操作代码都写在脚本中,这会让应用的代码耦合性太强,而且不利于代码的优化管理 一般应用都是使用MVC框架来设计的,为了更好地维持MVC结构 ...