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却先输出了,请问是哪里出错了?
...全文
416 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有时候会先输出来。能具体告诉我哪里的问题吗
内容概要:本文详细介绍了利用Simulink进行变压器开路试验的电路连接配置与仿真实现方法,重点在于通过仿真手段还原实际电力系统中变压器在空载条件下的电气特性,从而深入理解其工作原理与性能表现。文章作为电力系统仿真系列研究的一部分,系统阐述了从电路模型搭建、参数设定、仿真运行到结果分析的完整流程,突出展示了MATLAB/Simulink在电力设备建模与教学科研中的强大功能与应用价值。; 适合人群:具备电力系统基础知识,熟悉MATLAB/Simulink仿真环境,从事电气工程、自动化及相关领域的研发人员,以及高年级本科生和研究生。; 使用场景及目标:①掌握变压器开路试验的基本原理与Simulink仿真建模的具体步骤;②通过仿真实验深入理解空载电流、铁芯损耗及励磁特性等关键参数的物理意义;③为后续开展变压器短路试验、暂态过程分析以及其他电力设备的仿真研究奠定理论与实践基础。; 阅读建议:建议结合Simulink软件动手实践,逐步构建并调试电路模型,重点关注各元件参数的设置方法与测量模块的应用技巧,同时推荐参考文中提及的其他相关仿真案例进行拓展学习,以全面提升对电力系统仿真实践的整体认知与操作能力。

62,622

社区成员

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

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