java synchronized wait notify 生产者消费者死锁问题求解

问题描述

//仓库类publicclassWareHouse{//存货物的容器List<String>store=newArrayList<String>();publicWareHouse(){}//存货物的动作publicvoidstock(Stringproduct){synchronized(this){//往仓库中存一个货物System.out.println("卖家已经存入了货物:"+product+",通知等待得购买者");store.add(product);//通知购买者来取this.notify();}}//取货物的动作publicvoidbuy(){synchronized(this){if(store.size()==0){System.out.println("仓库目前没有货物,请等待。。。。");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}}Stringp=store.remove(0);System.out.println("买家已经买到了货物:"+p);}}//生产者类publicclassSellerimplementsRunnable{privateWareHousewareHouse;publicSeller(WareHousewareHouse){this.wareHouse=wareHouse;}@Overridepublicvoidrun(){for(inti=0;i<5000;i++){wareHouse.stock("product"+i);}}}//消费者类publicclassBuyerimplementsRunnable{privateWareHousewareHouse;//仓库publicBuyer(WareHousewareHouse){this.wareHouse=wareHouse;}@Overridepublicvoidrun(){for(inti=0;i<5000;i++){wareHouse.buy();}}}//测试类publicclassTestWareHouse{publicstaticvoidmain(String[]args){WareHousewareHouse=newWareHouse();Buyerbuyer=newBuyer(wareHouse);ThreadbuyThread=newThread(buyer);Sellerseller=newSeller(wareHouse);ThreadsellThread=newThread(seller);buyThread.start();sellThread.start();}}我的问题是在仓库类的buy方法中的两种写法写法1:synchronized(this){if(store.size()==0){System.out.println("仓库目前没有货物,请等待。。。。");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}}Stringp=store.remove(0);System.out.println("买家已经买到了货物:"+p);写法二synchronized(this){if(store.size()==0){System.out.println("仓库目前没有货物,请等待。。。。");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}Stringp=store.remove(0);System.out.println("买家已经买到了货物:"+p);}写法1会死锁写法2不会,区别就把Stringp=store.remove(0);System.out.println("买家已经买到了货物:"+p);放不放在synchronized中谁能给我解释下写法1死锁的原因吗?我还测试出写法一可能出现两次取出同一个物品的情况。。。求解

解决方案

解决方案二:
发代码用代码框在表情左边这么乱七八糟的谁看并且发帖前请使用预览功能确定代码缩进正确
解决方案三:
不好意思,是我太马虎了,现在调整过来了,你能帮忙解释下我的问题吗?麻烦了/***仓库类**@authorAdministrator**/publicclassWareHouse{//存货物的容器List<String>store=newArrayList<String>();publicWareHouse(){}//存货物的动作publicvoidstock(Stringproduct){synchronized(this){//往仓库中存一个货物System.out.println("卖家已经存入了货物:"+product+",通知等待得购买者");store.add(product);//通知购买者来取this.notify();}}//取货物的动作publicvoidbuy(){synchronized(this){if(store.size()==0){System.out.println("仓库目前没有货物,请等待。。。。");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}Stringp=store.remove(0);System.out.println("买家已经买到了货物:"+p);}}}//生产者类publicclassSellerimplementsRunnable{privateWareHousewareHouse;publicSeller(WareHousewareHouse){this.wareHouse=wareHouse;}@Overridepublicvoidrun(){for(inti=0;i<5000;i++){wareHouse.stock("product"+i);}}}//消费者类/***购买者*@authorAdministrator**/publicclassBuyerimplementsRunnable{privateWareHousewareHouse;//仓库publicBuyer(WareHousewareHouse){this.wareHouse=wareHouse;}@Overridepublicvoidrun(){for(inti=0;i<5000;i++){wareHouse.buy();}}}//测试类/***测试通信*@authorAdministrator**/publicclassTestWareHouse{publicstaticvoidmain(String[]args){WareHousewareHouse=newWareHouse();Buyerbuyer=newBuyer(wareHouse);ThreadbuyThread=newThread(buyer);Sellerseller=newSeller(wareHouse);ThreadsellThread=newThread(seller);buyThread.start();sellThread.start();}}我的问题是在仓库类的buy方法中的两种写法写法1:synchronized(this){if(store.size()==0){System.out.println("仓库目前没有货物,请等待。。。。");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}}Stringp=store.remove(0);System.out.println("买家已经买到了货物:"+p);写法2synchronized(this){if(store.size()==0){System.out.println("仓库目前没有货物,请等待。。。。");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}Stringp=store.remove(0);System.out.println("买家已经买到了货物:"+p);}写法1会死锁写法2不会,区别就把Stringp=store.remove(0);System.out.println("买家已经买到了货物:"+p);放不放在synchronized中谁能给我解释下写法1死锁的原因吗?我还测试出写法一可能出现两次取出同一个物品的情况。。。求解

解决方案四:
写法一是错误的写法一中remove操作没有synchronized保护是线程不安全的,因为这可能造成两个线程同时add或remove,或者一个在add,一个在remove,这样就不能保证这两个操作能正常进行,可能导致seller调用add不起作用,那么由于仓库中没有那么多货物(由于seller调用add失败导致部分货物没有添加),buyer就可能无限地等下去。同样是这个原因,如果你有两个buyer,那么可能remove了同一个货物。
解决方案五:
顺便说句回复别人请用“引用”功能,否则别人收不到通知说你回复了

时间: 2024-10-23 01:25:32

java synchronized wait notify 生产者消费者死锁问题求解的相关文章

JAVA synchronized 线程经典 生产者消费者 两个完全不同的实现的方式

package sell_ticket; public class ThreadTicket { public static void main(String[] args) { MyThread m = new MyThread(); Thread t1 = new Thread(m); Thread t2 = new Thread(m); Thread t3 = new Thread(m); t1.start(); t2.start(); t3.start(); } } class MyTh

java解决单缓冲生产者消费者问题示例_java

经典的生产者消费者问题模拟.此程序模拟最简单情形--单缓冲.为模拟实际情况,consume item和produce item时加了延时,可以通过修改延时模拟不同的生成消费速率. [code] [/co/** * single buffer consumer-producer problem. * by xu(xusiwei1236@163.com). * */public class ConsumerProducer {  static Object buffer = null;  stati

如何在 Java 中正确使用 wait, notify 和 notifyAll – 以生产者消费者模型为例

wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait.notify 和 notifyAll 来实现线程间的通信..举个例子,如果你的Java程序中有两个线程--即生产者和消费者,那么生产者可以通知消费者,让消费者开始消耗数据,因为队列缓冲区中有内容待消费(不为空).相应的,消费者可以通知生产者可以开始生成更多的数据,因为当它消耗掉某些数据后缓冲区不再

JAVA线程中的生产者和消费者问题

生产者消费者问题是研究多线程时绕不开的问题,描述的是有一块生产者和消费者共享的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品,这个过程可以无休止的执行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产品可取而终止. 解决生产者消费者问题的方法有两种,一种是采用某种机制保持生产者和消费者之间的同步,一种是在生产者和消费者之间建立一个管道.前一种有较高的效率并且可控制性较好,比较常用,后一种由于管道缓冲区不易控制及被传输数据对象不易封装等原因,比较少用. 同步问题的核心在

[Java] 多线程下生产者消费者问题的五种同步方法实现

版权声明:请尊重个人劳动成果,转载注明出处,谢谢! 目录(?)[+] 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题.    生产者消费者模式的优点 - 解耦 - 支持并发 - 支持忙闲不均 解决方法可分为两类:   (1)用信号量和锁机制实现生产者和消费者之间的同步:    - wait() / notify()方法  - await() / signal()方法  - BlockingQueue阻塞队列方法  - Semaphore方法    (2)在生产者和消费者之间建立一

java 生产者消费者问题 并发问题的解决(转)

引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品.互相等待,从而发生死锁. 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/

java 生产者消费者问题

引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品.互相等待,从而发生死锁. 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/

java实现生产者消费者问题(转)

引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品.互相等待,从而发生死锁. JAVA解决线程模型的三种方式 1.wait()和notify() import java.util.LinkedList; public class P

生产者消费者问题理解与Java实现

生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例.该问题描述了两个共享固定大小缓冲区的线程--即所谓的"生产者"和"消费者"--在实际运行时会发生的问题.生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程.与此同时,消费者也在缓冲区消耗这些数据.该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时