并发协作模型“生产者/消费者模式”
解决方法一、管程法
通过中间容器进行解决
该方法角色
- 生产者(多线程)对缓存区操作
- 消费者(多线程)对缓存区操作
- 中间缓存区容器(并发容器)实现存取操作
- 要操作的数据(听过并发容器来操作)
public class Cotest01 {
public static void main(String[] args) {
SynContainer container=new SynContainer();//创建缓存区
new Productor(container).start();//生产者线程
new Consumer(container).start();//消费者线程
}
}
//生产者
class Productor extends Thread{
SynContainer container;//对缓存区操作
public Productor(SynContainer container){
this.container=container;
}
public void run(){
//生产
for(int i=0;i<10;i++){
System.out.println("生产--->"+i+"个");
container.push(new Stearmedbun(i));
}
}
}
//消费者
class Consumer extends Thread{
SynContainer container;//对缓存区操作
public Consumer(SynContainer container){
this.container=container;
}
public void run(){
//消费
for(int i=0;i<10;i++){
System.out.println("消费--->"+container.pop().id+"个");
}
}
}
//缓冲区(操作数据)
class SynContainer{
Stearmedbun[] buns=new Stearmedbun[10];//存储数据容器
int count=0;//计数器 表示存储位置
//存储 生产
public synchronized void push(Stearmedbun bun){
//容器满时停止生产
if(count==buns.length){
try {
this.wait();//线程阻塞消费者通知生产则解除
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//容器存在空间则生产
buns[count]=bun;
count++;
this.notifyAll();//存在数据开始消费
}
//获取 消费
public synchronized Stearmedbun pop(){
//何时消费-》容器中有数据
//没有数据这等待
if(count==0){
try {
this.wait();//线程阻塞,当生产者通知时解除消费
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//有数据进行消费
count--;
Stearmedbun bun=buns[count];
this.notifyAll();//存在空间开始生产
return bun;
}
}
//操作数据
class Stearmedbun{
int id;
public Stearmedbun(int id) {
this.id = id;
}
}
信号灯法
借助标志位
该方法对象
- 生产者(多线程对象)
- 消费者(多线程对象)
- 生产者和消费者操作的共同资源(通过设置一个布尔值来改变操作对象)
/**
* 生产者消费者模式
* 信号灯发借助表示
*/
public class dxcXinhaodeng {
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<10;i++){
if(i%2==0){
this.tv.play("aaaaa");
}else {
this.tv.play("bbbbb");
}
}
}
}
//消费者 关众
class Watcher extends Thread{
TV tv;
public Watcher(TV tv){
this.tv=tv;
}
@Override
public void run() {
for(int i=0;i<10;i++){
tv.watch();
}
}
}
//同一个资源 电视
class TV{
String voice;
//信号灯
// True 表示演员表演观众等待
// false 表示观众观看演员等待
boolean flag=true;
//表演
public synchronized void play(String voice){
//演员等待
if(!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//表演
System.out.println("表演了"+voice);
this.voice=voice;
//唤醒
this.notifyAll();
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;
}
}