多线程-线程间通信-多生产者多消费者问题(JDK1.5后Lock,Condition解决办法及开发中代码范例)

1 package multithread4;
2
3 import java.util.concurrent.locks.Condition;
4 import java.util.concurrent.locks.Lock;
5 import java.util.concurrent.locks.ReentrantLock;
6
7 /*同步代码块对于锁的操作是隐式的
8 *
9 * jdk1.5以后将同步和锁封装成了对象。
10 * 并将操作锁的隐式方式定义到了该对象中,将隐式动作变成了显示动作
11 *
12 *
13 * Lock接口:出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成显式锁操作
14 * 同时更为灵活,可以一个锁上加上多组监视器。
15 * lock():获取锁
16 * unlock():释放锁,通常需要定义finally代码块中。
17 *
18 * Condition接口:出现替代了Object中的wait notify notifyAll方法。
19 * 将这些监视器方法单独进行了封装,变成Conditon监视器对象。
20 * 可以与任意锁进行组合
21 * await();
22 * signal();
23 * signalAll();
24 *
25 */
26
27
28 /*
29 * 生产者,消费者。
30 *
31 * 多生产者,多消费者的问题。
32 *
33 * if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。
34 * while判断标记,解决了线程获取执行权后,是否要运行!
35 *
36 * notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会产生死锁
37 * notifyAll解决了,本方线程一定会唤醒对方线程
38 *
39 * 死锁 四个线程都等待没有被唤醒也是一种情况,悬挂
40 */
41
42 class Resource2{
43 private String name;
44 private int count = 1;
45 private boolean flag = false;
46 //创建一个锁对象
47 Lock lock = new ReentrantLock();
48 //通过已有的锁获取该锁上的监视器对象。
49 // Condition con = lock.newCondition();
50
51 //通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。 用lock condition解决办法
52 Condition producer_con = lock.newCondition();
53 Condition consumer_con = lock.newCondition();
54
55 public void set(String name) {
56 lock.lock();
57 try {
58 /*if*/ while (flag) {
59 try {
60 // lock.wait();
61 // con.await();
62 producer_con.await();
63 } catch (InterruptedException e) {
64
65 }
66 }
67 this.name = name + count;
68 count++;
69 System.out.println(Thread.currentThread().getName()+"..生产者.."+this.name);
70 flag = true;
71 // notify();
72 // notifyAll();
73 // con.signalAll();
74 consumer_con.signal();
75 } finally {
76 lock.unlock();
77 }
78
79 }
80 public void out() {
81 lock.lock();
82 try {
83 /*if*/ while (!flag) {
84 try {
85 // con.await();
86 consumer_con.await();
87 } catch (InterruptedException e) {
88
89 }
90 }
91 System.out.println(Thread.currentThread().getName()+"..消费者......"+this.name);
92 flag = false;
93 // notify();
94 // notifyAll();//为了解决死锁 将其余三个都唤醒
95 // con.signalAll();
96 producer_con.signal();
97 } finally {
98 lock.unlock();
99 }
100
101 }
102
103 class Producer implements Runnable{
104 private Resource2 r;
105 public Producer(Resource2 r) {
106 this.r = r;
107 }
108 public void run() {
109 while(true) {
110 r.set("烤鸭");
111 }
112 }
113 }
114 class Consumer implements Runnable{
115 private Resource2 r;
116 public Consumer(Resource2 r) {
117 this.r = r;
118 }
119 public void run() {
120 while(true) {
121 r.out();
122 }
123 }
124 }
125 public class ProducerConsumerDemo2 {
126
127 public static void main(String[] args) {
128
129 Resource2 r = new Resource2();
130 Producer pro = new Producer(r);
131 Consumer con = new Consumer(r);
132
133 Thread t0 = new Thread(pro);
134 Thread t1 = new Thread(pro);
135 Thread t2 = new Thread(con);
136 Thread t3 = new Thread(con);
137
138 t0.start();
139 t1.start();
140 t2.start();
141 t3.start();
142 }
143
144 }
ProducerConsumerDemo2
多线程-线程间通信-多生产者多消费者问题(JDK1.5后Lock,Condition解决办法及开发中代码范例)的更多相关文章
- 多线程-线程间通信-多生产者多消费者问题解决(notifyAll)
1 package multithread4; 2 3 /* 4 * 生产者,消费者. 5 * 6 * 多生产者,多消费者的问题. 7 * 8 * if判断标记,只有一次,会导致不该运行的线程运行了. ...
- Java多线程——线程间通信
Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...
- 多线程 线程间通信 wait,notify
1. 方法wait锁释放,notify()锁不释放
- java多线程:线程间通信——生产者消费者模型
一.背景 && 定义 多线程环境下,只要有并发问题,就要保证数据的安全性,一般指的是通过 synchronized 来进行同步. 另一个问题是,多个线程之间如何协作呢? 我们看一个仓库 ...
- linux 信号量sem实现 生产者—消费者(线程间通信)
#include<pthread.h> #include<stdlib.h> #include<stdio.h> #include<unistd.h> ...
- java多线程与线程间通信
转自(http://blog.csdn.net/jerrying0203/article/details/45563947) 本文学习并总结java多线程与线程间通信的原理和方法,内容涉及java线程 ...
- Java——多线程之线程间通信
Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...
- Java多线程编程(6)--线程间通信(下)
因为本文的内容大部分是以生产者/消费者模式来进行讲解和举例的,所以在开始学习本文介绍的几种线程间的通信方式之前,我们先来熟悉一下生产者/消费者模式. 在实际的软件开发过程中,经常会碰到如下场景 ...
- 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题
调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...
随机推荐
- SpringBoot单元测试demo
引入maven <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- 【LeetCode】264. Ugly Number II 解题报告(Java & Python)
标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ https://leetcode.com/prob ...
- 【LeetCode】45. Jump Game II 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 贪心 日期 题目地址:https://leetcod ...
- 【LeetCode】875. Koko Eating Bananas 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 二分查找 日期 题目地址:https://leetc ...
- Optimization Landscape and Expressivity of DeepCNNs
目录 引 主要内容 基本的一些定义 卷积层 全连接层 池化层 改写卷积层 假设2.4 引理2.5 假设3.1 假设3.2 引理3.3 定理3.4 定理3.5 推论3.6 假设4.1 引理4.2 引理4 ...
- ECMA-262规范定义的七种错误类型
第一种:Error 所有错误的基本类型,实际上不会被抛出. 第二种:EvalError 执行eval错误时抛出. 第三种:ReferenceError 对象不存在是抛出. 第四种: ...
- SpringBoot 之 整合JDBC使用
导入相关依赖: # pom.xml <dependency> <groupId>org.springframework.boot</groupId> <art ...
- oracle 之 while循环月份
需求 需要跑一个数据,时间从17年5月到21年3月. 代码(简单粗暴实现) DECLARE i number; BEGIN i:= 201705; WHILE i <202104 LOOP if ...
- Nginx 防爬虫设置
在conf下 vi 一个文件agent_deny.conf 添加如下内容 #禁止Scrapy|curl等工具的抓取 if ($http_user_agent ~* (Scrapy|Curl|Http ...
- Centos7 mysqldump定时任务,对mysql定时备份数据
vi mysqldump_bak.sh #!/bin/bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/ ...