您的位置:首页 > 编程语言 > Java开发

java多线程二

2015-06-16 15:35 609 查看
对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的。

前面叙述生产消费者模型,仓库中存在单一产品的问题,

* 多线程生产者消费者模型

* 主要讲解线程同步问题,类Object中的wait,notify和notifyAll方法以及Synchronized关键字的使用

*

* 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。对于此模型,应该明确一下几点:

* 1、生产者仅仅在仓储未满时候生产,仓满则停止生产。

* 2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。

* 3、当消费者发现仓储没产品可消费时候会通知生产者生产。

* 4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。

* 此模型将要结合java.lang.Object的wait与notify、notifyAll方法来实现以上的需求。这是非常重要的。

public class Pc {

public static void main(String[] args) {
Godown godown = new Godown(50);
new Thread(new Produce(10, godown), "produce1").start();
new Thread(new Consume(godown, 20), "custom1").start();
new Thread(new Consume(godown, 20), "custom2").start();
new Thread(new Consume(godown, 20), "custom3").start();
new Thread(new Consume(godown, 20), "custom4").start();
new Thread(new Produce(10, godown), "produce2").start();
new Thread(new Produce(10, godown), "produce3").start();
new Thread(new Produce(10, godown), "produce4").start();
new Thread(new Produce(10, godown), "produce5").start();
new Thread(new Produce(10, godown), "produce6").start();
}
}

class Consume implements Runnable{
private Godown godown;
private int num ;
public Consume(Godown godown , int num){
this.godown = godown;
this.num=num;
}
@Override
public void run() {
godown.consume(num);
}
}

class Produce implements Runnable{
private Godown godown ;
private int num ;
public Produce(int num , Godown godown){
this.godown = godown;
this.num = num;
}
@Override
public void run() {
godown.produce(num);
}
}

class Godown{
private static final int MAX_SIZE = 100;
private int curnum ;

public Godown() {
}
public Godown(int curnum){
this.curnum = curnum;
}

public synchronized void produce(int num){
while(curnum+num > MAX_SIZE){
try {
System.out.println(Thread.currentThread().getName()+" 生产数量:"+num+"+库存:"+curnum+">最大容量,produce线程wait");
wait();
System.out.println(Thread.currentThread().getName()+" 生产线程被唤醒,继续运行。");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
curnum+=num;
System.out.println(Thread.currentThread().getName()+"生产了:"+num+"个,目前产品数量:"+curnum);
notifyAll();
}

public synchronized void consume(int num){
while(num>curnum){
try {
System.out.println(Thread.currentThread().getName()+" 消费数量:"+num+" +库存"+curnum+" 超出库存最大容量,custom等待");
wait();
System.out.println(Thread.currentThread().getName()+"消费线程被唤醒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
curnum-=num;
System.out.println(Thread.currentThread().getName()+"消费了:"+num+"个,目前产品数量为:"+curnum);
notifyAll();
}
}


运行结果:

produce1生产了:10个,目前产品数量:60
custom1消费了:20个,目前产品数量为:40
custom2消费了:20个,目前产品数量为:20
custom3消费了:20个,目前产品数量为:0
custom4 消费数量:20 +库存0 超出库存最大容量,custom等待
produce2生产了:10个,目前产品数量:10
custom4消费线程被唤醒
custom4 消费数量:20 +库存10 超出库存最大容量,custom等待
produce3生产了:10个,目前产品数量:20
custom4消费线程被唤醒
custom4消费了:20个,目前产品数量为:0
produce4生产了:10个,目前产品数量:10
produce5生产了:10个,目前产品数量:20
produce6生产了:10个,目前产品数量:30
</pre><pre name="code" class="java">运行流程


当custom4进行消费时,发现curnum=0,custom4进入线程池中等待,等待生产者进行生产,

当produce2和produce3生产出满足消费的数量时,custom4被唤醒并进行消费。

...................................
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: