Java多线程(8):并发协作_生产者消费者模式(管程法、红绿灯法)

一、生产者消费者模式

1、解决的是线程通信的问题。(解耦、效率高)
2、管程法:生产者和消费者之间设置一个缓冲区,生产者和消费者之间的耦合度较低,维护简单。(解耦)
在这里插入图片描述
3、红绿灯法

二、解决线程通信问题的三个方法

1、final void wait():表示线程一直等待,直到其他线程通知,与sleep()不同,会释放锁。
2、final void wait(long timeout):指定等待的毫秒数。
3、final void notify():唤醒一个处于等待状态的线程.
4、final void notifiAll():唤醒同一个对象上的所调用wait()方法的线程,由此按级别高的线程优先调度。
以上的方法都只能在同步方法或者同步块中使用,否则会抛出异常

三、管程法

下面数据缓冲区大小为10进行生产者消费者模式

/**
 * 生产者消费者模式一:管程
 * @author 鹏鹏
 *
 */
public class CorperationTest {
	public static void main(String[] args) {
		SynContainer synContainer = new SynContainer();
		new Thread(new Productor(synContainer)).start();
		new Thread(new Customer1(synContainer)).start();
	}
}



//生产者
class Productor implements Runnable{
	SynContainer syncontainer;
	public Productor(SynContainer syncontainer) {
		this.syncontainer = syncontainer;
	}
	
	@Override
	public void run() {
		for(int i=0;i<100;i++)
		{
			System.out.println("生产-->"+i+"个数据");
			syncontainer.push(new Data(i));
		}
		
	}
}

//消费者
class Customer1 implements Runnable{
	
	SynContainer syncontainer;
	public Customer1(SynContainer syncontainer) {
		// TODO 自动生成的构造函数存根
		this.syncontainer = syncontainer;
	}
	@Override
	public void run() {
		for(int i=0;i<100;i++)
		{
			System.out.println("消费-->"+syncontainer.pop().id+"个数据");
			
		}
	}
}


//缓冲区
class SynContainer {
	Data[] data  = new Data[10];			//缓冲区大小10个数据
	int count = 0;							//计数器
	
	//存储,生产
	public synchronized void push(Data data1) {
		//何时生产,容器存在空间
		//不能生茶,就等待
		if(count == data.length) {
			try {
				this.wait();						//消费者通知生产就解除
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		
		//存在数据通知消费
		data[count] = data1;
		count++;
		this.notifyAll();
	}
	
	
	//获取数据,消费
	public synchronized Data pop() {
		
		//看容器中是否存在数据,没有数据只能等待
		if(count==0) {
			try {
				this.wait();							 //此时线程阻塞,生产者通知消费就解除阻塞
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		
		//存在数据可以消费
		count--;
		Data data2 = data[count];			//获取最后一个数据
		//存在空间唤醒对方生产
		this.notifyAll();
		return data2;
	}
}


//数据
class Data{
	int id;
	public Data(int id) {
		this.id = id;
	}
}

四、红绿灯法

/**
 * 生产者消费者模式信号灯法,借助标志位,举例关账收看节目
 * @author 鹏鹏
 *
 */

public class CorperationTestTrafficLights {
	public static void main(String[] args) {
		Tv tv = new Tv();
		new Thread(new Actor(tv)).start();
		new Thread(new Audience(tv)).start();
	}
}


//生产者演员
class Actor implements Runnable{
	Tv tv;
	public Actor(Tv tv) {
		this.tv = tv;
	}
	public void run() {
		for(int i=0;i<20;i++) {
			if(i%2==0) {
				this.tv.play("西游记");
			}else {
				this.tv.play("广告");
			}
		}
	}
}



//消费者观众
class Audience implements Runnable{
	Tv tv;
	public Audience(Tv tv) {
		this.tv = tv;
	}
	public void run() {
		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) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		
		//演员表演
		System.out.println("发出了了"+voice);
		this.voice = voice;
		this.notifyAll();
		flag = !flag;
	}
	
	
	
	//观看
	public synchronized void watch() {
		//观众等待
		if(flag) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		
		//观众观看
		System.out.println("听到了"+voice);
		this.notifyAll();
		flag = !flag;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coder鹏鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值