package com.mozq.thread.producer2;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 当使用等待时
* 如果用if会造成,线程被唤醒时不管条件是否满足,都会执行任务代码。产生错误。
* 改用while,每次线程被唤醒时会进行条件判断,是否满足。但是产生了死锁问题。
* 1.通过使用notifyAll而不是notify方法来解决死锁。
* 单生产者和单消费者不会因使用while发生死锁,因为,线程池中只有 一个另一方的线程,notify方法必然会唤醒另一方的线程。
* 多生产者和多消费者的等待集中有生产方和消费方的线程,notify方法可能会唤醒本方线程而不是另一方,造成 死锁。
*
* Condition对象可以为表示锁的一个等待集,一个锁可以产生多个Condition对象也就是等待集。并对它们分别进行操作。
* 针对多生产者和多消费者,我们可以分别为生产者和消费者创建一个等待集,并在唤醒时,调用另一方等待集的通知,确保唤醒的是另一方线程。避免了死锁。
*
* @author jie
*
*/
class Resource{
private String name = null;
private int count = 0;
private boolean set = false;
private Lock lock = new ReentrantLock();
private Condition producer = lock.newCondition();
private Condition consumer = lock.newCondition(); public void set(String name) {
lock.lock();
try {
//如果已经存在资源,等待
while(set) {
try {
producer.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//没有资源就创建
count++;
this.name = name + count;
System.out.println(Thread.currentThread().getName() + "生产。"+ this.name);
set = true;
//同时消费者消费
consumer.signal();
}finally {
lock.unlock();
}
} public void out() {
lock.lock();
try {
//如果没有产品,等待
while(!set) {
try {
consumer.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//有就消费
System.out.println(Thread.currentThread().getName() + "消费。。。。。"+ this.name);
set = false;
//通知生产者生产
producer.signal();
} finally {
lock.unlock();
}
}
} class Input implements Runnable{
private Resource r;
public Input(Resource r) {
this.r = r;
} @Override
public void run() {
while(true) {
r.set("烤鸡");
}
} }
class Output implements Runnable{
private Resource r;
public Output(Resource r) {
this.r = r;
} @Override
public void run() {
while(true) {
r.out();
}
} } public class ProducerConsumerDemo {
public static void main(String[] args) {
//创建资源
Resource r = new Resource();
//创建任务
Input in = new Input(r);
Output out = new Output(r);
//创建线程
Thread t0 = new Thread(in);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
Thread t3 = new Thread(out);
//开启线程
t0.start();
t1.start();
t2.start();
t3.start();
}
}

生产者消费者 java.util.concurrent.lock包的更多相关文章

  1. Java:多线程,java.util.concurrent.atomic包之AtomicInteger/AtomicLong用法

    1. 背景 java.util.concurrent.atomic这个包是非常实用,解决了我们以前自己写一个同步方法来实现类似于自增长字段的问题. 在Java语言中,增量操作符(++)不是原子的,也就 ...

  2. Java并发—java.util.concurrent.locks包

    一.synchronized的缺陷 synchronized是java中的一个关键字,也就是说是Java语言内置的特性.那么为什么会出现Lock呢? 如果一个代码块被synchronized修饰了,当 ...

  3. JDK源码学习之 java.util.concurrent.automic包

    一.概述 Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下无锁的进行原子操作.原子变量的底层使用了处理器提供的原子指令,但是不同的CP ...

  4. Java并发—原子类,java.util.concurrent.atomic包(转载)

    原子类 Java从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中 的原子操作类提供了一种用法简单.性能高效.线程安全地更新一个变量 ...

  5. java.util.concurrent.atomic 包详解

    Atomic包的作用: 方便程序员在多线程环境下,无锁的进行原子操作 Atomic包核心: Atomic包里的类基本都是使用Unsafe实现的包装类,核心操作是CAS原子操作 关于CAS compar ...

  6. 《java.util.concurrent 包源码阅读》02 关于java.util.concurrent.atomic包

    Aomic数据类型有四种类型:AomicBoolean, AomicInteger, AomicLong, 和AomicReferrence(针对Object的)以及它们的数组类型, 还有一个特殊的A ...

  7. java.util.concurrent包

    在JavaSE5中,JUC(java.util.concurrent)包出现了 在java.util.concurrent包及其子包中,有了很多好玩的新东西: 1.执行器的概念和线程池的实现.Exec ...

  8. java.util.concurrent.atomic 类包详解

    java.util.concurrent包分成了三个部分,分别是java.util.concurrent.java.util.concurrent.atomic和java.util.concurren ...

  9. 并发之java.util.concurrent.atomic原子操作类包

    15.JDK1.8的Java.util.concurrent.atomic包小结 14.Java中Atomic包的原理和分析 13.java.util.concurrent.atomic原子操作类包 ...

随机推荐

  1. MongoDB 学习一

    这一章,我们先介绍几个MongoDB的概念: 1.document: 它是MongoDB的基础数据单元,它大概等价于关系型数据库中的行. 2.collection: 可以想象成动态的表. 3.一个简单 ...

  2. ABAP 动态内标排序

     动态内表怎样排序动态内表怎样排序 动态内表要排序时,因为不知道内表中的字段名字,所以不能直接用SORT table BY field1 field2... 可以使用下面的方法来实现:SORT tab ...

  3. Impala 安装笔记1一Cloudera CDH4.3.0安装

    Impala是Cloudera在受到Google的Dremel启发下开发的实时交互SQL大数据查询工具,Impala没有再使用缓慢的Hive+MapReduce批处理,而是通过使用与商用并行关系数据库 ...

  4. Mall电商项目总结(二)——nginx负载均衡配置和策略

    1. nginx配置文件 用户在浏览器上输入,http://www.xwld.site/ 实际上是在访问服务器80端口,nginx 监听80端口,将用户的请求转发到8080和9080端口 . upst ...

  5. selenium使用笔记(一)——selenium你该知道的

    有时候在交流群里经常会看到这样的问题,selenium能进行性能测试吗?selenium1和selenium2有什么区别等等问题,在这里谈一下自己学习和工作以后对selenium的认识.我所记录的东西 ...

  6. 关于Javascript中声明变量、函数的笔记

    一.概念 1.变量声明 在JavaScript中,变量一般通过var关键字(隐式声明,let关键字声明除外)进行声明,如下通过var关键字声明a,b,c三个变量(并给其中的a赋值): var a=1, ...

  7. BZOJ1566 【NOI2009】管道取珠

    题面 这是一道DP神题,直到我写下这句题解时也没有想明白…… 首先,这道题要我们求所有(不同输出序列的方案数)的平方和,于是我们当然就想到求所有不同输出序列的方案数……(大雾) .这道题一个巧妙的地方 ...

  8. codeforces 665B B. Shopping(水题)

    题目链接: B. Shopping time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  9. java实现EXCEL数据导入到数据库中的格式问题的解决

    之前作为项目甲方,加之java接触不多,在java web开发方面都是打下手的份. 对于EXCEL数据导入到数据库这个问题一直老是出现格式原因而导入失败也是未免惆怅,开发团队也是只说回去检查一下格式. ...

  10. Notepad++安装xml插件

    环境: win7 64位 Notepad++7.3.3 原生的Notepad++不自带xml文件的插件,所以在显示xml文件时并不分行(如下图所示),对于用户编辑,查看的操作而言,并不友好,所以需要安 ...