生产者消费者 java.util.concurrent.lock包
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包的更多相关文章
- Java:多线程,java.util.concurrent.atomic包之AtomicInteger/AtomicLong用法
1. 背景 java.util.concurrent.atomic这个包是非常实用,解决了我们以前自己写一个同步方法来实现类似于自增长字段的问题. 在Java语言中,增量操作符(++)不是原子的,也就 ...
- Java并发—java.util.concurrent.locks包
一.synchronized的缺陷 synchronized是java中的一个关键字,也就是说是Java语言内置的特性.那么为什么会出现Lock呢? 如果一个代码块被synchronized修饰了,当 ...
- JDK源码学习之 java.util.concurrent.automic包
一.概述 Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下无锁的进行原子操作.原子变量的底层使用了处理器提供的原子指令,但是不同的CP ...
- Java并发—原子类,java.util.concurrent.atomic包(转载)
原子类 Java从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中 的原子操作类提供了一种用法简单.性能高效.线程安全地更新一个变量 ...
- java.util.concurrent.atomic 包详解
Atomic包的作用: 方便程序员在多线程环境下,无锁的进行原子操作 Atomic包核心: Atomic包里的类基本都是使用Unsafe实现的包装类,核心操作是CAS原子操作 关于CAS compar ...
- 《java.util.concurrent 包源码阅读》02 关于java.util.concurrent.atomic包
Aomic数据类型有四种类型:AomicBoolean, AomicInteger, AomicLong, 和AomicReferrence(针对Object的)以及它们的数组类型, 还有一个特殊的A ...
- java.util.concurrent包
在JavaSE5中,JUC(java.util.concurrent)包出现了 在java.util.concurrent包及其子包中,有了很多好玩的新东西: 1.执行器的概念和线程池的实现.Exec ...
- java.util.concurrent.atomic 类包详解
java.util.concurrent包分成了三个部分,分别是java.util.concurrent.java.util.concurrent.atomic和java.util.concurren ...
- 并发之java.util.concurrent.atomic原子操作类包
15.JDK1.8的Java.util.concurrent.atomic包小结 14.Java中Atomic包的原理和分析 13.java.util.concurrent.atomic原子操作类包 ...
随机推荐
- WIN7系统设置wifi
*&->20170302 112700 WIN7系统设置wifi, 开启win7的隐藏功能,即虚拟wifi功能和虚拟无线AP功能,即可实现将电脑变成wifi 供无线上网, 1.开始-命令 ...
- [IR课程笔记]概率检索模型
几个符号意义: R:相关文档集 NR:不相关文档集 q:用户查询 dj:文档j 1/0风险情况 PRP(probability ranking principle):概率排序原理,利用概率模型来估计每 ...
- 最简单ajax,$.post()用法
最简单的ajax,$.post()用法 $.post("action.php",{'email':$('#email').val(),'address':$('#address') ...
- 盒子的display属性
<body> <div style="display:inline">Box-1</div> <div style="displ ...
- HDU2896 病毒侵袭 —— AC自动机
题目链接:https://vjudge.net/problem/HDU-2896 病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit ...
- 调试windows服务最简单的方法之一
先看一下这段启动代码: using System; using System.Collections.Generic; using System.Linq; using System.ServiceP ...
- 17.for循环语句
for循环: 语法: for(表达式1;表达式2;表达式3){ java语句; } 表达式1是最初始化表达式:最先执行,只执行一次 表达式2必须是boolean 类型的表达式.结果为ture或者fal ...
- CodeForces 1111E. Tree
题目简述:给定$n \leq 10^5$个节点的无根树,以及$q \leq 10^5$个询问.每个询问给定$k \leq 10^5$个不同的节点$a_1, a_2, \dots, a_k$,以及参数$ ...
- 2.13 Hive中自带Function使用及自定义UDF编程
UDF:User Definition Function 一.function #查看自带的函数 hive (db_hive)> show functions; #查看一个函数的详细用法 hiv ...
- IP地址库解析——读取IP地址获得实际地理位置信息的java源码实现
说明:IP地址库来自QQwry.dat数据库文件,通过解析地址库当中的ip,已经细化最后获取的信息:获取ip地址对应的:国家 / 省 / 市 / 运营商ISP信息. 解析主要用到三个类: (1) IP ...