Java学习之线程通信(多线程(synchronized))--生产者消费者

分析线程经典案例生产者消费者

 1 /**
 2 共享数据
 3 */
 4 class Resource
 5 {
 6     private String name;
 7     private int count=1;
 8     private boolean flag=false;
 9
10     public synchronized void set(String name)
11     {
12         if(flag)
13             try{this.wait();}catch(InterruptedException e){}
14         this.name=name+count;
15         count++;
16         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
17         flag = true;
18         notify();
19     }
20
21     public synchronized void out()
22     {
23         if(!flag)
24             try{this.wait();}catch(InterruptedException e){}
25         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
26         flag = false;
27         notify();
28     }
29 }
30
31 //定义线程任务(生产者线程)
32 class Producer implements Runnable
33 {
34     private Resource r;
35
36     Producer(Resource r)
37     {
38         this.r=r;
39     }
40     public void run()
41     {
42         while(true)
43         {
44             r.set("商品");
45         }
46     }
47 }
48 //定义线程任务(消费者线程)
49 class Consumer implements Runnable
50 {
51     private Resource r;
52
53     Consumer(Resource r)
54     {
55         this.r=r;
56     }
57
58     public void run()
59     {
60         while(true)
61         {
62             r.out();
63         }
64     }
65 }
66
67 class ProducerConsumerDemo
68 {
69     public static void main(String[] args)
70     {
71         //实例化共享资源
72         Resource r = new Resource();
73         //实例化线程任务,指定共享资源
74         Producer p=new Producer(r);
75         Consumer c=new Consumer(r);
76         //实例化线程,指定线程任务
77         Thread t0=new Thread(p);
78         Thread t1=new Thread(p);
79         Thread t2=new Thread(c);
80         Thread t3=new Thread(c);
81         //开启线程,执行线程任务中的run方法
82         t0.start();
83         t1.start();
84         t2.start();
85         t3.start();
86     }
87 }

运行结果:

结果分析:

那么怎么再判断flag呢?while

代码如下:

 1 class Resource
 2 {
 3     private String name;
 4     private int count=1;
 5     private boolean flag=false;
 6
 7     public synchronized void set(String name) // 有两个线程t0 t1
 8     {
 9         while(flag)
10             try{this.wait();}catch(InterruptedException e){}
11         this.name=name+count;
12         count++;
13         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
14         flag = true;
15         notify();
16     }
17
18     public synchronized void out() // 有两个线程t2 t3
19     {
20         while(!flag)
21             try{this.wait();}catch(InterruptedException e){}
22         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
23         flag = false;
24         notify();
25     }
26 }

结果出现死锁:

结果分析:

通过分析,那能不能每次唤醒只唤醒对方线程(如生产者线程只唤醒消费者线程,消费者线程只唤醒生产者线程),查看Object对象方法中没有,但是有一个notifyAll()方法,实在不行就把所有阻塞线程(相同同步锁的线程)都唤醒。

 1 class Resource
 2 {
 3     private String name;
 4     private int count=1;
 5     private boolean flag=false;
 6
 7     public synchronized void set(String name) // 有两个线程t0 t1
 8     {
 9         while(flag)
10             try{this.wait();}catch(InterruptedException e){}
11         this.name=name+count;
12         count++;
13         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
14         flag = true;
15         notifyAll();
16     }
17
18     public synchronized void out() // 有两个线程t2 t3
19     {
20         while(!flag)
21             try{this.wait();}catch(InterruptedException e){}
22         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
23         flag = false;
24         notifyAll();
25     }
26 }

结果:

这样就可以了。

总结:

if判断只能判断一次,如果执行等待方法,下次唤醒的线程获取执行权后(唤醒后的线程会从上次等待位置,向下执行)就不能再判断

while判断解决唤醒的线程获取执行权后无法判断

notify:只能唤醒任意一个线程,有可能会唤醒本方线程,while+notify会导致死锁

notifyAll:解决了死锁问题

原文地址:https://www.cnblogs.com/WarBlog/p/12082961.html

时间: 2024-08-07 12:59:43

Java学习之线程通信(多线程(synchronized))--生产者消费者的相关文章

java基础——线程通信机制,生产者消费者

package communication; /* 使用两个线程1,2交替打印1-100 线程通信方法: 1.wait():一旦执行此方法,当前线程进入阻塞态,并释放锁 2.notify():会唤醒被wait的一个线程,如果有多个线程wait,则唤醒优先级高的 3.notifyAll():唤醒所有被wait的线程 说明: 1.wait(),notify(),notifyAll()使用在同步代码块或同步方法中,不能用在lock方法中 2.这三个方法的调用者必须是同步代码块或同步方法中的锁对象(同步

java中多线程通信实例:生产者消费者模式

线程间的通信: 其实就是多个线程再操作同一个资源,但是操作的动作不同   当某个线程进入synchronized块后,共享数据的状态不一定满足该线程的需要,需要其他线程改变共享数据的状态后才能运行,而由于当时线程对共享资源时独占的,它必须解除对共享资源的锁定的状态,通知其他线程可以使用该共享资源. Java中的 wait(),notify(),notifyAll()可以实现线程间的通信. 生产者--消费者问题是典型的线程同步和通信问题 /** * 生产者和消费者问题,生产者生成出产品,消费者去购

JAVA多线程之生产者消费者

生产者消费者并发编程: 假设仓库有10个仓位,分别有10个生产者和10个消费者,生产者不断生产产品,放入仓库的仓位中,而消费者则不断从仓库中获取产品, 如果仓库已满,则生产者要等待,等消费者消费后,空出仓位后,再继续放入产品. 反之如果仓库已空,则消费者要等待,等待生产者生产出产品后,再继续消费产品. 关于生产者.消费者有四种实现方式 1,wait,nofity方式 2,ReentrantLock锁的await()和signal() 3,阻塞队列的方式 4,Semaphore 信号量方式 下面分

java多线程解决生产者消费者问题

import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class Test { public static void main(String[] args) { GunClip clip = new GunClip(); Producer p = new Producer(clip); customer c = new customer(clip); p.star

java多线程模拟生产者消费者问题,公司面试常常问的题。。。

package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 //Storage仓库 //批注:我把输出结果写在程序以下了,你能够看一下,事实上非常easy的,你想象一下产品从生产,到取出的一个生产线,我们定义两个线程,生产者线程,和消费者线程,一个是生产者不停的生产产品并放入数量有限的指定槽内,而消费者从指定槽依次取出产品,现实中的流水车间也相似于此. publ

java中的线程通信

原文链接 作者:Jakob Jenkov 译者:杜建雄  校对:方腾飞 java中线程通信的目标是使线程间能够互相发送信号.另一方面,线程通信使线程能够等待其他线程的信号. 例如,线程B可以等待线程A的一个信号,这个信号会通知线程B数据已经准备好了. 1.通过共享对象通信 java学习中线程间发送信号的一个简单方式是在共享对象的变量里设置信号值.线程A在一个同步块里设置boolean型成员变量hasDataToProcess为true,线程B也在同步块里读取hasDataToProcess这个成

Android-Java多线程通讯(生产者 消费者)&10条线程对-等待唤醒/机制的管理

上一篇博客 Android-Java多线程通讯(生产者 消费者)&等待唤醒机制 是两条线程(Thread-0 / Thread-1) 在被CPU随机切换执行: 而今天这篇博客是,在上一篇博客Android-Java多线程通讯(生产者 消费者)&等待唤醒机制 的基础上,扩大规模增加10条线程去执行 生产者 消费者: 注意:?? 上一篇博客是两条线程在执行(生产者 消费者)例如:当Thread-0 锁.wait(); 等待 冻结后,  Thread-1 锁.notify(); 唤醒的一定是 T

java笔记--关于线程通信

关于线程通信 使用多线程编程的一个重要原因就是线程间通信的代价比较小 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3897773.html "谢谢-- 关键技术: yield(): Thread类的一个静态方法,用来暂停当前正在执行的线程对象,并执行其他线程 public static void yield(){} 代码实例: 实现线程间的发送和接收消息 package com.xhj.thread; /** * 线程之间的通信

多线程应用——生产者消费者问题

前言 生产者和消费者问题是多线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加产品,消费者从存储空间中取走产品,当存储空间为空时,消费者阻塞,当存储空间满时,生产者阻塞. 在JAVA中实现生产者消费者问题时,有三种常用的方式: 使用Object的wait/notify的消息通知机制 使用Lock的Condition的await/signal的消息通知机制 使用BlockingQueue实现.本文主要将这三种实现方式进行总结归纳 下面本文将分别采用以上三种