JAVA多线程同步问题(3个生产者,2个消费者)

suzhan7 2008-10-15 08:39:33

class CubbyHole {
int num;
boolean key=false;

public synchronized int get(){
while(!key){
try{
wait();
}catch(InterruptedException e){}
}
key=false;
notify();
return num;
}

public synchronized void put(int i){
while(key){
try{
wait();
}catch(InterruptedException e){}
}
num=i;
key=true;
notify();
}

}


class Producer extends Thread{
int n1;
private CubbyHole ch;
public Producer(CubbyHole c,int num ){
ch=c;
this.n1=num;
}

public void run(){
for(int k=0;k<3;k++){
int i=(int)(Math.random()*100+1);
ch.put(i);
System.out.println("Producter"+n1+" put"+i);
try{
sleep((int)(Math.random()*100));
}catch(InterruptedException e){}
}
}
}

class Consumer extends Thread{
private CubbyHole ch;
public int n2;
public Consumer(CubbyHole c ,int num){
ch=c;
this.n2=num;
}

public void run(){
int value=0;
for(int k=0;k<3;k++){
value=ch.get();
System.out.println("Consumer"+n2+" get"+value);
try{
sleep((int)(Math.random()*100));
}catch(InterruptedException e){}
}
}
}


public class Test {
public static void main(String[] args) {
CubbyHole ch=new CubbyHole();
Producer p1=new Producer(ch,1);
Producer p2=new Producer(ch,2);
Producer p3=new Producer(ch,3);
Consumer c1=new Consumer(ch,1);
Consumer c2=new Consumer(ch,2);

p1.start();
p2.start();
p3.start();
c1.start();
c2.start();
}

}
==================
有的时候会输出这样的情况:
Consumer2 get83
Producter2 put83
Consumer1 get13
Producter3 put35
Producter1 put13
Consumer2 get35
Producter3 put27
Producter1 put36
Consumer2 get27
Consumer1 get36
Producter2 put20
Consumer1 get20
Producter3 put76
消费者的get却先输出了,请问是哪里出错了?
...全文
369 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
KitChan 2011-08-15
  • 打赏
  • 举报
回复
是因为有两个消费者线程造成的 还有输出语句应该放在synchronized的put和get方法中
suzhan7 2008-10-16
  • 打赏
  • 举报
回复
我已经用synchronized线程琐来锁住put和get方法了
jourqel 2008-10-16
  • 打赏
  • 举报
回复
也就是说可以控制你的线程哪个先执行~
jourqel 2008-10-16
  • 打赏
  • 举报
回复
搂上说得对~start只是说这个线程被提交到可运行池~但是什么时候执行这个是由cpu分配的~所以在你没有设定条件的情况下是无法决定哪个线程先执行~不过,你可以通过设置线程的优先级来使哪个线程先执行~同时通过synchronized线程琐来控制访问机制~并配合wait()sleep()和noitfy()方法来控制~这样虽然线程执行的顺序是由cpu自动分配的~不过这样控制可以让你的消费者的get不先输出~
gs840120 2008-10-16
  • 打赏
  • 举报
回复
顶2楼
线程问题测试的时候总是出各种问题,现在我也在学习ing
nine_suns99 2008-10-16
  • 打赏
  • 举报
回复
因为start只是告诉虚拟机这个线程可以运行了,但是什么时候运行,谁先运行这个都是有虚拟机和操作系统共同决定的,出现这种情况很正常。
suzhan7 2008-10-16
  • 打赏
  • 举报
回复
这个题我已经锁住了get和put。感觉是输出那块有问题,我尝试锁住
value=ch.get();
System.out.println("Consumer"+n2+" get"+value);
try{
sleep((int)(Math.random()*100));
}catch(InterruptedException e){}

但还是不对,get有时候会先输出来。能具体告诉我哪里的问题吗

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧