首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

多线程的通信有关问题,麻烦大家帮小弟我看看

2012-01-30 
多线程的通信问题,麻烦大家帮我看看如果加上try{Thread.sleep(1)}catch(Exceptionw){}(24行-27行)要求的

多线程的通信问题,麻烦大家帮我看看
如果加上try{Thread.sleep(1);}catch(Exception   w){}(24行-27行)要求的打印的效果没问题
张宇,男
李梅,女
张宇,男
李梅,女
但是没有上面那个sleep就不行了
这是为什么呀!!!???请各位帮帮忙~~~谢谢
class   Q
{
String   name   =   "unknown ";
String   sex   =   "unknown ";
boolean   bFull   =   false;


}
class   producer   implements   Runnable
{
Q   q   =   null;

public   producer(Q   q)
{
this.q   =   q;
}
public   void   run()
{
int   i   =0   ;
while(true)
{

synchronized(q)
{
if(q.bFull)
try{wait();}
catch(Exception   w){}
if(i==0)
{
try{Thread.sleep(1);}
catch(Exception   w){}
q.name   =   "张宇 ";
q.sex   =   "男 ";
}
else
{
q.name   =   "李梅 ";
q.sex   =   "女 ";
}
i   =   (i+1)%2;
q.bFull   =   true;
q.notify();
}

}
}
}
class   customer   implements   Runnable
{
Q   q   =   null;
//int   j   =   0;
public   customer(Q   q)
{
this.q   =   q;
}
public   void   run()
{

while(true)
{
synchronized(q)
{
if(!q.bFull)
try{wait();}
catch(Exception   w){}
System.out.println(q.name+   "-----> "   +   q.sex);
q.bFull   =   false;
q.notify();
}
}
}
}

class   TestThread
{
public   static   void   main(String   []   args)
{
Q   q   =   new   Q();
new   Thread(new   producer(q)).start();
new   Thread(new   customer(q)).start();
}
}

[解决办法]
作为生产者和消费者用一个对象做队列肯定是不对的。因为q.notify();有可能唤醒的是生产者也可能是消费者
class Q
{
String name = "unknown ";
String sex = "unknown ";
boolean bFull = false;
}
class ProducterQ{
Q q;
public ProducterQ(Q q){
this.q=q;
}
}
class CustomerQ{
Q q;
public CustomerQ(Q q){
this.q=q;
}
}
class producer implements Runnable
{
ProducterQ pq = null;
CustomerQ cq=null;

public producer(ProducterQ pq,CustomerQ cq)
{
this.pq = pq;
this.cq = cq;
}
public void run()
{
int i =0 ;
while(true)
{

synchronized(pq)
{
while(pq.q.bFull){
try{
pq.wait();
}
catch(Exception w){}
}
if(i==0)
{
pq.q.name = "张宇 ";
pq.q.sex = "男 ";
}
else
{
pq.q.name = "李梅 ";
pq.q.sex = "女 ";
}
i = (i+1)%2;
pq.q.bFull = true;

}
synchronized(cq)
{
cq.notify();


}

}
}
}
class customer implements Runnable
{
CustomerQ cq = null;
ProducterQ pq = null;
//int j = 0;
public customer(ProducterQ pq,CustomerQ cq)
{
this.cq = cq;
this.pq = pq;
}
public void run()
{

while(true)
{

synchronized(cq)
{
while(!cq.q.bFull){
try{
cq.wait();
}
catch(Exception w){}
}
System.out.println(cq.q.name+ "-----> " + cq.q.sex);
cq.q.bFull = false;

}
synchronized(pq)
{
pq.notify();
}
}
}
}

public class TestThread
{
public static void main(String [] args)
{
Q q = new Q();
ProducterQ pq=new ProducterQ(q);
CustomerQ cq=new CustomerQ(q);
new Thread(new producer(pq,cq)).start();
new Thread(new customer(pq,cq)).start();
}
}
[解决办法]
only issue of the lock , don 't need create ProducterQ and CustomerQ .

public class TestThread
{
public static void main(String [] args)
{
Q q = new Q();
Object lock1 =new Object();
Object lock2 =new Object();
new Thread(new producer(q,lock1,lock2)).start();
new Thread(new customer(q,lock1,lock2)).start();
}
}
[解决办法]
notify()
方法不能确定唤醒的是哪个线程
按官方的说法是唤醒顺序完全没有规则....
不按优先级,也不按前后顺序...

热点排行