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 ...
随机推荐
- ThreadPoolExcuter源码解析(一)
1.ThreadPoolExcuter原理说明 首先我们要知道为什么要使用ThreadPoolExcuter,具体可以看看文档中的说明: 线程池可以解决两个不同问题:由于减少了每个任务的调用开销,在执 ...
- compose合并函数依次执行 - 来源redux
function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1 ...
- Struts2中数据封装方式
一.通过ActionContext类获取 public class ActionContextDemo extends ActionSupport { @Override public S ...
- Flask开发微电影网站(一)
1.用到的Flask知识 1.使用整形,浮点型,路径型,字符串型下正则表达式路由转化器 2.使用GET与POST请求,上传文件,cookie获取与响应,404处理 3.使用模板自动转义,定义过滤器,定 ...
- Java开发岗面试知识点解析
本文作者参加过多场面试,应聘岗位均为 Java 开发方向.在不断的面试中,分类总结了 Java 开发岗位面试中的一些知识点. 主要包括以下几个部分: Java 基础知识点 Java 常见集合 高并发编 ...
- Base64 image
[前端攻略]:玩转图片Base64编码 什么是 base64 编码? 我不是来讲概念的,直接切入正题,图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址. 这样 ...
- sublime安装AngularJS插件
sublime能够支持AngularJS开发那绝对是一件很爽的事情.下面我一步步讲解如何为sublime安装AngularJS插件. 1.添加控制包站点 根据你安装sublime 版本不同,在控制台写 ...
- Python中标准模块importlib详解
1 模块简介 Python提供了importlib包作为标准库的一部分.目的就是提供Python中import语句的实现(以及__import__函数).另外,importlib允许程序员创建他们自定 ...
- SPU和SKU有什么区别
SPU = Standard Product Unit (标准产品单位)SPU是商品信息聚合的最小单位,是一组可复用.易检索的标准化信息的集合,该集合描述了一个产品的特性.通俗点讲,属性值.特性相同的 ...
- fasthttp 的 goroutine pool 实现探究
引言 fasthttp是一个非常优秀的web server框架,号称比官方的net/http快10倍以上.fasthttp用了很多黑魔法.俗话说,源码面前,了无秘密,我们今天通过源码来看一看她的gor ...