生产者消费者 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原子操作类包 ...
随机推荐
- PAT 天梯赛 L2-008. 最长对称子串 【字符串】
题目链接 https://www.patest.cn/contests/gplt/L2-008 思路 有两种思路 第一种 遍历每一个字符 然后对于每一个 字符 同时 往左 和 往右 遍历 只要 此时 ...
- 青岛理工ACM交流赛 J题 数格子算面积
数格子算面积 Time Limit: 1000MS Memory limit: 262144K 题目描述 给你一个多边形(用’\’和’/’表示多边形的边),求多边形的面积. 输入 第一行两个正整数h ...
- 关于lock锁
在 jdk1.5 之后,并发包中新增了 Lock 接口(以及相关实现类)用来实现锁功能,Lock 接口提供了与 synchronized 关键字类似的同步功能,但需要在使用时手动获取锁和释放锁. lo ...
- codeforces 469B Chat Online 解题报告
题目链接:http://codeforces.com/problemset/problem/469/B 题目意思:给出 Little Z 的上线时间段,分别是[a1, b1], [a2, b2],.. ...
- html5--4-3 source元素-解决浏览器的兼容
html5--4-3 source元素-解决浏览器的兼容 学习要点 掌握source元素的用法 source元素-解决浏览器额兼容 HTML5 中新增的元素 video和audio元素的子元素,可指定 ...
- Git基本用法1
二.git的初始化 在使用git进行代码管理之前,我们首先要对git进行初始化. 1.Git 配置 使用Git的第一件事就是设置你的名字和email,这些就是你在提交commit时的签名,每次提交记录 ...
- Java网络编程Socket通信
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议 UDP (User Datagram Proto ...
- hdu-5665 Lucky(水题)
题目链接: Lucky Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Pro ...
- Ubuntu 16.04上安装SkyEye及测试
说明一下,在Ubuntu 16.04上安装SkyEye方法不是原创,是来自互联网,仅供学习参考. 一.检查支持软件包 gcc,make,vim(optional),ssh,subversionbinu ...
- bootstrap 学习笔记(1)---介绍bootstrap和栅格系统
学习前端许久,对于布置框架和响应浏览器用html 和javascript 写的有点繁琐,无意间看到这个框架,觉得挺好用的就开始学习了,但是这个框架上面有很多知识,不是所有的都要学的,故将学习笔记和觉得 ...