站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2SE 专题关于多线程和wait()、notity()的问题

关于多线程和wait()、notity()的问题

摘要: 关于多线程和wait()、notity()的问题


class Store
{
int goods;
boolean haveGoods=false;
synchronized void putGoods(int i)
{
if(haveGoods==false)
{
goods=i;
haveGoods=true;
notify();
try
{
wait();
}
catch(Exception e)
{
}

}
}
synchronized int getGoods()
{

if(haveGoods==false)
{
try
{
wait();
}
catch(Exception e)
{
}
}
haveGoods=false;
notify();
return goods;
}
}

class Consturcter extends Thread
{
Store s;
Consturcter(Store s)
{
this.s=s;
}
public void run()
{
for(int i=0;i<10;i++)
{
s.putGoods(i);
System.out.println("Now "+i+" goods has been put in Store");
}
}

}

class Consumer extends Thread
{
Store s;
Consumer(Store s)
{
this.s=s;
}
public void run()
{
while(true)
{
//s.getGoods();
System.out.println("Now goods "+s.getGoods()+" has been got by consumer");
}
}
}

class GetOneByPutOne
{
public static void main(String[] args)
{
Store s=new Store();
Consturcter cst=new Consturcter(s);
Consumer csu=new Consumer(s);
cst.start();
csu.start();
}
}

一个生产者生产一个产品放入商店中,生产10个商品
一个消费者从商店取走商品
一个商店用做存放和取走商品
这段代码是想完成“生产一个马上取走一个”的任务
为什么这段代码执行结果前面都是正确的,到了8和9就变成了“先拿走后生产”了啊?这显然不符合逻辑啊~~我错在哪呢?


我的运行结果是~
Now 0 goods has been put in Store
Now goods 0 has been got by consumer
Now 1 goods has been put in Store
Now goods 1 has been got by consumer
Now 2 goods has been put in Store
Now goods 2 has been got by consumer
Now 3 goods has been put in Store
Now goods 3 has been got by consumer
Now 4 goods has been put in Store
Now goods 4 has been got by consumer
Now 5 goods has been put in Store
Now goods 5 has been got by consumer
Now 6 goods has been put in Store
Now goods 6 has been got by consumer
Now 7 goods has been put in Store
Now goods 7 has been got by consumer
Now goods 8 has been got by consumer
Now 8 goods has been put in Store
Now goods 9 has been got by consumer
Now 9 goods has been put in Store

注意8和9完全就是先get后put~~狂汗~!


我运行了该程序,正常,没有问题,我用的是JCreator


我跑下来的结果
---------- Java ----------
Now 0 goods has been put in Store
Now goods 0 has been got by consumer
Now goods 1 has been got by consumer
Now 1 goods has been put in Store
Now goods 2 has been got by consumer
Now 2 goods has been put in Store
Now 3 goods has been put in Store
Now goods 3 has been got by consumer
Now 4 goods has been put in Store
Now goods 4 has been got by consumer
Now goods 5 has been got by consumer
Now 5 goods has been put in Store
Now goods 6 has been got by consumer
Now 6 goods has been put in Store
Now goods 7 has been got by consumer
Now 7 goods has been put in Store
Now 8 goods has been put in Store
Now goods 8 has been got by consumer
Now goods 9 has been got by consumer
Now 9 goods has been put in Store

首先分析问题 问题出在你的打印语句
//这个方法执行等待另一个方法使用notify才能完毕,而是这时候getgoods()已经打印完毕
s.putGoods(i);
//这时候再打印就出现反应结果滞后的问题
System.out.println("Now "+i+" goods has been put in Store");

解决方法把打印语句放到修改结果的语句下面 就ok了



补充一点 以便全接50分
synchronized int getGoods(){
notify();//这步之后 另外一个线程回到ready state并不是马上执行完毕的,所以读取快一步
return goods;
}


学习一下


syoumei(赚满1000专家分去考认证)
补充一点 以便全接50分
synchronized int getGoods(){
notify();//这步之后 另外一个线程回到ready state并不是马上执行完毕的,所以读取快一步
return goods;
}
这个我看懂了~但前面的一篇回复我没看懂~能说详细点吗?


syoumei(赚满1000专家分去考认证) 你说得不全对~但在你的提示下我弄正确了

问题确实出在打印结果前已经唤醒了另一个线程。
但解决方法并不是你所说的“把打印语句放到修改结果的语句下面 就ok了”,那样也许表面看上去结果正确,但如果循环很长时间后会发现错误还是存在,因此错误的根本原因在于唤醒线程和打印结果是两段语句,中间存在时间间隙。
因此,正确的修改方法应该是将打印语句放到修改结果的方法中去。这样就做到了完全没有时间间隙了。程序运行再长时间也不会出现顺序混乱的问题了
不知道我说得对不对,如果有问题请更正




一句话来说你的插入方法要等待读取方法结束了才能结束
所以你打印的顺序有出入


因此,正确的修改方法应该是将打印语句放到修改结果的方法中去。
解决方法 把打印语句放到修改结果的语句下面 就ok了
---------------------------------------------------------
汗 不是我错,而是你刚刚理解对了

给你2个方法
private void create(int ){
this.i=i
打印
修改标志位

}

private int cancel(){
打印
修改标志位
return i
}

然后在getGoods putGoods 里调用


↑返回目录
前一篇: java小游戏的移植
后一篇: JAVA里面比较两个数的问题