问题描述
//仓库类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了同一个货物。
解决方案五:
顺便说句回复别人请用“引用”功能,否则别人收不到通知说你回复了