java-多线程管程法,信号灯法

【摘要】 java-多线程管程法,信号灯法
1.管程法:
生产者:负责生产数据的模块(可能是方法,对象,线程,进程) 消费者:负责处理数据的模块(可能是方法,对象,线程,进程) 缓冲区:消费者不能直接使用生产者的数据,他们之间有个缓冲区,生产者将生产好的数据放入缓冲区,消费者从缓冲区拿出数据
思路: 1.首先有一个生产者,消费者、生产者只顾生产,消费者只管消费 2.利用了一…

java-多线程管程法,信号灯法

1.管程法:

生产者:负责生产数据的模块(可能是方法,对象,线程,进程)
消费者:负责处理数据的模块(可能是方法,对象,线程,进程)
缓冲区:消费者不能直接使用生产者的数据,他们之间有个缓冲区,生产者将生产好的数据放入缓冲区,消费者从缓冲区拿出数据

思路:
1.首先有一个生产者,消费者、生产者只顾生产,消费者只管消费
2.利用了一个缓冲区,缓冲了一个10个大小的数组
3.有个方法叫放入产品,产品丢进来的时候,我们判断一下缓冲区有没有满,如果满了的话,生产者就要等待了,
如果没有满,就将产品放进去,放进去之后有产品了,赶紧通知消费者消费
4.消费者就判断下能不能消费呢,有没有东西,有东西的话,我就可以直接消费,消费完了,就赶紧通知生产者生产。
如果没有东西呢,消费者就等待。等待生产者去通知他,生产者通知了,他就可以解除等待了,所以在这一块存在我们的wait()和notify()。
这里的wait()和notify()都是Object提供的:
wait()导致当前线程等待,直到另一个线程调用该对象的notify()或notifyAll()方法。
notify()唤醒正在等待对象监视器的单个线程。
一旦加了wait()之后同样是进入了阻塞状态,但是这个阻塞和之前的sleep()不一样,它会释放锁,被wait()的线程可以把这个锁交给其他线程去用,否则这个资源就一直被其持有了。

思路有了那么就开始代码部分了:

(1)创建生产者

// 生产者
class Productor extends Thread{ SynContainer container; public Productor(SynContainer container){ this.container = container; } // 生产 @Override public void run() { for (int i = 0; i < 100; i++) { container.push(new Bug(i)); System.out.println("生产了"+i+"个bug"); } }
}
  
 

(2)创建消灭者

// 消灭bug者
class Consumer extends Thread{ SynContainer container; public Consumer(SynContainer container){ this.container = container; } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("消灭了-->"+container.pop().id+"个bug"); } }
}

  
 

(3)创建bug区(产品区)

// bug产品
class Bug{ int id;// bug编号 public Bug(int id){ this.id = id; }
}

  
 

(4)创建同步代码块(缓冲区)

// 缓冲区
class SynContainer{ // 需要一个容器大小 Bug[] bugs = new Bug[10]; // 容器计算器 int count = 0; // 生产者放入bug public synchronized void push(Bug bug){ // 如果容器满了,就需要等待消灭bug if(count==bugs.length){ // 通知消灭bug者消灭,生产bug等待 try { //导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。 this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 如果没有满,我们就需要继续生产bug bugs[count] = bug; count++; // 可以通知消灭者消灭了 this.notifyAll(); // notifyAll唤醒正在等待对象监视器的所有线程。 } // 消灭者消灭bug public synchronized Bug pop(){ // 判断能否消灭 if (count == 0){ // 等待生产者生产,消灭者等待 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 如果可以消灭 count--; Bug bug = bugs[count]; // 消灭完了,通知生产者生产 return bug; }
}
  
 

保证容器中没有产品的时候生产产品,不能消费;容器中产品满了的时候,不能再去生产产品

(5)创建测试类

public class Test { public static void main(String[] args) { SynContainer container = new SynContainer(); new Productor(container).start(); new Consumer(container).start(); }
}

  
 

(6)测试
在这里插入图片描述

很完美的把全部bug都消灭了

2.信号灯法:

先来理解下信号灯法是什么意思:来判断一个标志位flag,如果为true,就让他等待、如果为false,就让他去通知另外一个人、把两人衔接起来,就像咱们的信号灯红灯停,绿灯行,通过这样一个判断方式,只要来判断什么瑞后让他等待,什么时候将他唤醒就ok。

话不多说直接上代码^^

package com.macro.mall.bo;
//测试生产者消费者问题2:信号灯法,通过标志位解决

public class Test { public static void main(String[] args) { TV tv = new TV(); new Player(tv).start(); new Watcher(tv).start(); }
}

//生产者-->演员
class Player extends Thread { TV tv; public Player(TV tv) { this.tv = tv; } @Override public void run() { for (int i = 0; i < 20; i++) { if (i % 2 == 0) { this.tv.play("什么是快乐星球"); } else { this.tv.play("如果你想知道什么是快乐星球的话,那我就带你研究研究"); } } }
}

//消费者-->观众
class Watcher extends Thread { TV tv; public Watcher(TV tv) { this.tv = tv; } @Override public void run() { for (int i = 0; i < 20; i++) { tv.watch(); } }
}

//产品-->节目
class TV { //演员表演,观众等待 T //观众观看,演员等待 F String voice; // 表演的节目 boolean flag = true; //表演 public synchronized void play(String voice) { if (!flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("演员表演了:" + voice); //通知观众观看 this.notifyAll(); this.voice = voice; this.flag = !this.flag; } //观看 public synchronized void watch() { if (flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("观看了:" + voice); //通知演员表演 this.notifyAll(); this.flag = !this.flag; }
}

  
 

第一篇文章,感谢家人们的阅读

文章来源: blog.csdn.net,作者:Java中的kids,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/ClearloveRelink/article/details/115656855

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享