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解决办法及开发中代码范例)的更多相关文章

  1. 多线程-线程间通信-多生产者多消费者问题解决(notifyAll)

    1 package multithread4; 2 3 /* 4 * 生产者,消费者. 5 * 6 * 多生产者,多消费者的问题. 7 * 8 * if判断标记,只有一次,会导致不该运行的线程运行了. ...

  2. Java多线程——线程间通信

    Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...

  3. 多线程 线程间通信 wait,notify

    1. 方法wait锁释放,notify()锁不释放

  4. java多线程:线程间通信——生产者消费者模型

    一.背景 && 定义 多线程环境下,只要有并发问题,就要保证数据的安全性,一般指的是通过 synchronized 来进行同步. 另一个问题是,多个线程之间如何协作呢? 我们看一个仓库 ...

  5. linux 信号量sem实现 生产者—消费者(线程间通信)

    #include<pthread.h> #include<stdlib.h> #include<stdio.h> #include<unistd.h> ...

  6. java多线程与线程间通信

    转自(http://blog.csdn.net/jerrying0203/article/details/45563947) 本文学习并总结java多线程与线程间通信的原理和方法,内容涉及java线程 ...

  7. Java——多线程之线程间通信

    Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...

  8. Java多线程编程(6)--线程间通信(下)

      因为本文的内容大部分是以生产者/消费者模式来进行讲解和举例的,所以在开始学习本文介绍的几种线程间的通信方式之前,我们先来熟悉一下生产者/消费者模式.   在实际的软件开发过程中,经常会碰到如下场景 ...

  9. 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题

    调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...

随机推荐

  1. 【LeetCode】760. Find Anagram Mappings 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历 日期 题目地址:https://leetcode ...

  2. 【LeetCode】1041. Robot Bounded In Circle 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 找规律 日期 题目地址:https://leetco ...

  3. 【剑指Offer】04. 二维数组中的查找 解题报告(Java & Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 日期 题目地址:https://leetcode-cn.com/ ...

  4. Go语言核心36讲(新年彩蛋)--学习笔记

    新年彩蛋 | 完整版思考题答案 基础概念篇 Go 语言在多个工作区中查找依赖包的时候是以怎样的顺序进行的? 答:你设置的环境变量GOPATH的值决定了这个顺序.如果你在GOPATH中设置了多个工作区, ...

  5. webservice websocket socket http rpc

    HTTP: HTTP 是基于请求响应式的,即通信只能由客户端发起,服务端做出响应,无状态,无连接. webSocket: 服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向 ...

  6. [error]Flask Address already in use

    在Python的Flask框架下Address already in use [地址已在使用中] 出现这种错误提示, 说明你已经有一个流程绑定到默认端口(5000).如果您之前已经运行过相同的模块,则 ...

  7. Java实习生常规技术面试题每日十题Java基础(三)

    目录 1.是否可以从一个static方法内部发出对非static方法的调用? 2.Integer与int的区别? 3.Overload和Override的区别.参数列表相同,返回值不同的方法,是否是重 ...

  8. JS事件冒泡与事件捕获怎么理解?

    在js中存在事件冒泡与事件捕获两种概念,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题. 事件冒泡(dubbed bubbling) 事件冒泡我们从字面意思理解就是当用户行为触发我们页面的定 ...

  9. Java初学者作业——编写 Java 程序,定义 Java 类 (Point) 用来表示坐标,坐标范围在(0,0)到(100,100)以内,并显示合法的坐标在控制台。

    返回本章节 返回作业目录 需求说明: 编写 Java 程序,定义 Java 类 Point 用来表示坐标,坐标范围在(0,0)到(100,100)以内,并显示合法的坐标在控制台. 实现思路: 定义 P ...

  10. ECMA-262规范定义的七种错误类型

    第一种:Error    所有错误的基本类型,实际上不会被抛出.   第二种:EvalError   执行eval错误时抛出. 第三种:ReferenceError    对象不存在是抛出. 第四种: ...