多线程问题

kelly0924 2009-12-17 11:48:13
/*5个生产者,1个篮子,3个消费者;
其中每个生产者一次能生产20个产品,并将产品放入篮子;
篮子总共能放5个产品;
消费者每次从篮子顶端取出产品消费;*/
public class ProducterConsumer
{
public static void main(String[] args)
{
SyncStack ss = new SyncStack();
Producer p1 = new Producer(ss);
Producer p2 = new Producer(ss);
Producer p3 = new Producer(ss);
Producer p4 = new Producer(ss);
Producer p5 = new Producer(ss);
Consumer c1 = new Consumer(ss);
Consumer c2 = new Consumer(ss);
Consumer c3 = new Consumer(ss);
new Thread(p1).start();
new Thread(p2).start();
new Thread(p3).start();
new Thread(p4).start();
new Thread(p5).start();
new Thread(c1).start();
new Thread(c2).start();
new Thread(c3).start();
}
}

class ChanPin
{
public static int counter = 0;
private int id;

public ChanPin()
{
this.id = counter++;
}

public String toString()
{
return "产品" + id;
}
}
//篮子
class SyncStack
{
int index = 0;
ChanPin[] arrCP = new ChanPin[5];

public synchronized ChanPin push(ChanPin cp)
{
while(index == arrCP.length)
{
System.out.println("篮子满了");
try
{
//pop();
this.wait();
}
catch (Exception e)
{
e.printStackTrace();
}
}
this.notifyAll();//让所有的线程从wait中恢复过来,继续执行后面的语句
System.out.println("??????"+cp);
arrCP[index] = cp;
index++;
System.out.println("生产一个产品,篮子里有+++++>" + index + "个");
return cp;
}

public synchronized ChanPin pop()
{
while(index == 0)
{
System.out.println("篮子空了");
try
{
System.out.println("index "+index);
this.wait();
}
catch (Exception e)
{
e.printStackTrace();
}
}
this.notifyAll();
index--;
System.out.println("消费一个产品,篮子里有----->" + index + "个");
return arrCP[index];
}
}
//生产者
class Producer implements Runnable
{
SyncStack ss = null;

Producer(SyncStack ss)
{
this.ss = ss;
}

public void run()
{
for(int i=0; i<20; i++)
{
ChanPin cp = new ChanPin();
ss.push(cp);
try
{
Thread.sleep((int)(Math.random()*10));
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
//消费者
class Consumer implements Runnable
{
SyncStack ss = null;

Consumer(SyncStack ss)
{
this.ss = ss;
}

public void run()
{
for(int i=0; i<20; i++)
{
ss.pop();
try
{
Thread.sleep((int)(Math.random()*10));
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}



执行结果如下:
??????产品0
生产一个产品,篮子里有+++++>1个
??????产品1
生产一个产品,篮子里有+++++>2个
??????产品2
生产一个产品,篮子里有+++++>3个
??????产品3
生产一个产品,篮子里有+++++>4个
??????产品4
生产一个产品,篮子里有+++++>5个
消费一个产品,篮子里有----->4个
消费一个产品,篮子里有----->3个
消费一个产品,篮子里有----->2个
??????产品5
生产一个产品,篮子里有+++++>3个
??????产品6
生产一个产品,篮子里有+++++>4个
??????产品7
生产一个产品,篮子里有+++++>5个
消费一个产品,篮子里有----->4个
消费一个产品,篮子里有----->3个
消费一个产品,篮子里有----->2个
??????产品9
生产一个产品,篮子里有+++++>3个
??????产品8
生产一个产品,篮子里有+++++>4个
??????产品10
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品12
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品14
生产一个产品,篮子里有+++++>5个
消费一个产品,篮子里有----->4个
消费一个产品,篮子里有----->3个
??????产品13
生产一个产品,篮子里有+++++>4个
??????产品11
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品17
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
消费一个产品,篮子里有----->3个
??????产品19
生产一个产品,篮子里有+++++>4个
??????产品18
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品21
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
消费一个产品,篮子里有----->3个
??????产品22
生产一个产品,篮子里有+++++>4个
??????产品15
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品20
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品24
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品16
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品25
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品28
生产一个产品,篮子里有+++++>5个
消费一个产品,篮子里有----->4个
??????产品27
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品31
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品26
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品33
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品23
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品32
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品29
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品35
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品37
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品38
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品39
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品34
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品30
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品40
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品44
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品36
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品45
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品41
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品46
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品48
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品49
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品50
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品52
生产一个产品,篮子里有+++++>5个
消费一个产品,篮子里有----->4个
??????产品51
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品54
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品43
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品55
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品42
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品56
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品47
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品59
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品53
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品61
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
消费一个产品,篮子里有----->3个
??????产品57
生产一个产品,篮子里有+++++>4个
??????产品58
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品63
生产一个产品,篮子里有+++++>5个
消费一个产品,篮子里有----->4个
??????产品62
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品67
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
篮子满了
消费一个产品,篮子里有----->4个
??????产品68
生产一个产品,篮子里有+++++>5个
篮子满了
篮子满了
篮子满了
篮子满了
篮子满了

疑问:为什么不出现篮子空了的情况呢??线程停止的条件是什么??初学者,见笑了,谢谢指教……
...全文
201 13 打赏 收藏 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
islandrabbit 2009-12-19
  • 打赏
  • 举报
回复
不要用this.notifyAll();

用this.notify();
wmdtksmld 2009-12-19
  • 打赏
  • 举报
回复
哥们儿貌似在跟马士兵学哦,呵呵
wibnmo 2009-12-19
  • 打赏
  • 举报
回复
问题1:处理机每次的调度是不同的,为线程分配的时间片也不一样。
多运行几次。会出现空篮子的情况。

问题2:生产者线程多于消费者线程,而且循环次数都是20次,所以不会停止。
改进方法一:
让生产者线程也是3个,这样就能正常停止。
改进方法二:
把消费者线程的循环次数改大一些比方说循环40次,但这还不够,这样还不会停止,
因为篮子空的情况而被阻塞。
把消费者线程改为守护线程就行了:

Thread t1 = new Thread(c1);
Thread t2 = new Thread(c1);
Thread t3 = new Thread(c1);
t1.setDaemon(true);
t2.setDaemon(true);
t3.setDaemon(true);
t1.start();
t2.start();
t3.start();

守护线程是为用户线程服务,垃圾回收机制就是一守护线程。
当生产者这个用户线程停止时,消费者这个守护线程也自动终止。
SambaGao 2009-12-18
  • 打赏
  • 举报
回复
我知道什么原因了。
是因为你的生产者太多了。
当还没有消费完就有生产了。所以只能满了。
你可以去掉两个生产都。空了就出来了。
记住。this.notify() ;
public class SyncStack {

int index = 0;
ChanPin[] arrCP = new ChanPin[5];

public synchronized ChanPin push(ChanPin cp) {
while (index == arrCP.length) {
System.out.println("篮子满了");
try {
// pop();
this.wait();

} catch (Exception e) {
e.printStackTrace();
}
}
this.notifyAll();// 让所有的线程从wait中恢复过来,继续执行后面的语句
System.out.println("??????" + cp);
arrCP[index] = cp;
index++;
this.notify() ;
System.out.println("生产一个产品,篮子里有+++++>" + index + "个");
return cp;
}

public synchronized ChanPin pop() {
while (index == 0) {
System.out.println("篮子空了");
try {
System.out.println("index " + index);
this.wait();

} catch (Exception e) {
e.printStackTrace();
}
}

index--;
this.notify() ;
System.out.println("消费一个产品,篮子里有----->" + index + "个");
return arrCP[index];
}

}
kelly0924 2009-12-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 groovy2007 的回复:]
notify的位置不对。
应该加在做完事情之后。
push函数加在这个地方:
index++; 
this.notifyAll();

pop函数里应该加在这个地方
index--;
this.notifyAll();

但是你的程序不会结束的原因不在于此,而在于生产了100个产品,而只消费了60个,
因此剩下的40个产品里面有35个永远在排队,等待加入 ChanPin[] arrCP数组中,所以程序永远也不会结束。

[/Quote]
this.notifyAll()的位置改了,但还是不会出现篮子空的情况……
liu_liyang 2009-12-18
  • 打赏
  • 举报
回复
换个思路吧。。让生产者少点。或者让生产者睡眠的时间长点!
groovy2007 2009-12-18
  • 打赏
  • 举报
回复
notify的位置不对。
应该加在做完事情之后。
push函数加在这个地方:
index++;
this.notifyAll();

pop函数里应该加在这个地方
index--;
this.notifyAll();

但是你的程序不会结束的原因不在于此,而在于生产了100个产品,而只消费了60个,
因此剩下的40个产品里面有35个永远在排队,等待加入 ChanPin[] arrCP数组中,所以程序永远也不会结束。
kelly0924 2009-12-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 nihaozhangchao 的回复:]
在篮子满了时候就是this.wait();方法后加一个this.notify()触发一个下一个线程执行。
在空了的时候也加上。消费都也加上。
线程停止的条件是stop()就行了。
[/Quote]
我有加notify(),但还是不行哦……
SambaGao 2009-12-18
  • 打赏
  • 举报
回复
http://zhangjunhd.blog.51cto.com/113473/71387
SambaGao 2009-12-18
  • 打赏
  • 举报
回复
在篮子满了时候就是this.wait();方法后加一个this.notify()触发一个下一个线程执行。
在空了的时候也加上。消费都也加上。
线程停止的条件是stop()就行了。
kelly0924 2009-12-18
  • 打赏
  • 举报
回复
大家帮忙看一下嘛……谢谢……
Busing 2009-12-18
  • 打赏
  • 举报
回复
生产者消费者问题阿
你的生产者比消费者多,而且生常速度和消费速度也差不多,所以你的程序 一般情况 不会停止
smallbear923 2009-12-18
  • 打赏
  • 举报
回复
学习~

62,620

社区成员

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

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