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的更多相关文章

  1. Java 多线程-生产者、消费者

    一.整体代码 ThreadDemo.java public class ThreadDemo { public static void main(String[] args) { Godown god ...

  2. JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题

    JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序猿杜鹏程的博客:http://blog ...

  3. Windows下RabbitMQ 的下载、配置、Java实现生产者和消费者例子

    RabbitMQ是一个轻量级的消息代理中间件,支持多种消息通信协议,支持分布式部署,支持运行于多个操作系统,具有灵活.高可用等特性.RabbitMQ支持多种协议,其中最为重要的是高级消息队列协议(AM ...

  4. java实现生产者和消费者问题

    Java实现生产者和消费者问题 欢迎访问我的个人博客,获取更多有用的东西 链接一 链接二 也可以关注我的微信订阅号:CN丶Moti

  5. Java中生产者与消费者模式

    生产者消费者模式 首先来了解什么是生产者消费者模式.该模式也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例.该问题描述了两个共享固定大小缓冲区的线 ...

  6. Java实现生产者和消费者

    生产者和消费者问题是操作系统的经典问题,在实际工作中也常会用到,主要的难点在于协调生产者和消费者,因为生产者的个数和消费者的个数不确定,而生产者的生成速度与消费者的消费速度也不一样,同时还要实现生产者 ...

  7. python多线程+生产者和消费者模型+queue使用

    多线程简介 多线程:在一个进程内部,要同时干很多事情,就需要同时执行多个子任务,我们把进程内的这些子任务叫线程. 线程的内存空间是共享的,每个线程都共享同一个进程的资源 模块: 1._thread模块 ...

  8. java之生产者与消费者

    package com.produce; import java.util.LinkedList; import java.util.Queue; /*@author shijin * 生产者与消费者 ...

  9. java线 生产者和消费者

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlhbmdydWkxOTg4/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

随机推荐

  1. css基础--深入理解弹性盒flex布局

    欢迎访问我的个人博客:http://www.xiaolongwu.cn 1. 前言 flex弹性盒,是一种布局方式,当页面需要适应不同的屏幕大小以及设备类型时,它依然能确保元素 拥有更恰当的排布行为, ...

  2. IDEA设置生成带注释的getter和setter解决方案 (图文教程)

    近日在研究重构代码的时候有用到idea的不少插件,比如CheckStyle,同时下载了阿里的开发规约,收到不少启发. 规约中会要求所有的方法都有Javadoc,但是通常我们用idea默认生成的gett ...

  3. PAT1094:The Largest Generation

    1094. The Largest Generation (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yu ...

  4. SSM-MyBatis-06:Mybatis中openSession到底做了什么

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 1.找SqlSesionFactory实现类 Ctrl+H:DefaultSqlSessionFactory: ...

  5. Linux kernel的中断子系统之(三):IRQ number和中断描述符

    返回目录:<ARM-Linux中断系统>. 总结: 二描述了中断处理示意图,以及关中断.开中断,和IRQ number重要概念. 三介绍了三个重要的结构体,irq_desc.irq_dat ...

  6. 修改WordPress后台默认登陆地址提高网站安全性

    作者:荒原之梦 原文链接:http://zhaokaifeng.com/?p=536 安装完WordPress后,默认的登陆地址就是: http://XXX.XXX/wordpress/wp-admi ...

  7. Spring Batch 专题

    如今微服务架构讨论的如火如荼.但在企业架构里除了大量的OLTP交易外,还存在海量的批处理交易.在诸如银行的金融机构中,每天有3-4万笔的批处理作业需要处理.针对OLTP,业界有大量的开源框架.优秀的架 ...

  8. Netty与网络编程

    Netty什么? Netty项目是一个提供异步事件驱动网络应用框架和快速开发可维护的高性能高扩展性服务端和客户端协议工具集的成果.换句话说,Netty是一个NIO客户端服务端框架,它使得快速而简单的开 ...

  9. storage.go

    package storage import (     "fmt"     "os" ) const DEFAULT_STORAGE_ENGINE = &qu ...

  10. BZOJ_2502_清理雪道_有源汇上下界最小流

    BZOJ_2502_清理雪道_有源汇上下界最小流 Description        滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道), ...