JAVA线程学习2(生产者与消费者)

1.生产者与消费者问题

解决方式1:(管道法)生产者将生产好的数据放入“缓冲区”,消费者从“缓冲区”拿走要处理的数据。

解决方式2:(信号灯法)

解决线程通信的方法
方法名作用
final void wait()表示线程一直等待,直到其他线程通知,与sleep不同,会释放锁
final  void wait(long tiimeout)指定等待的毫秒数
final void notify()唤醒一个处于等待状态的线程
final void notifyAll()唤醒同一个对象上所有调用wait()方法的线程,优先级别高的线程优先调度

 

 

 

 

 

 

2.代码实现

      1.管道法

package cn.zwl.cooperation;
/**
 * 
 * 生产者消费者的实现方式一:管道法
 * @author dell
 *角色1:生产者
 *角色2:消费者
 *角色3:缓冲区
 *角色4:馒头
 *
 *
 *
 */
class Producter extends Thread{
	SynContainer container;
	
	public Producter(SynContainer container) {
		super();
		this.container = container;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		for (int i = 0; i < 100; i++) {
			System.out.println("生产第"+i+"个馒头");
			container.push(new SteamedBun(i));
		}
		
	}
}
class Comsumer extends Thread{
SynContainer container;

	public Comsumer(SynContainer container) {
	super();
	this.container = container;
}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		for (int i = 0; i < 100; i++) {
			System.out.println("消费第"+container.pop().id+"个馒头");
			
		}
	}
}
class SynContainer{
		SteamedBun[] buns=new SteamedBun[10];
		int count=0;//计数器
		//存储 生产
		public synchronized void push(SteamedBun bun) {
			//何时生产,容器存在空间
			if(count==buns.length) {
				try {
					this.wait();//线程阻塞,消费者通知生产解除
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			buns[count]=bun;
			count++;
			this.notifyAll();//存在数据可以消费
		}
		//获取 消费
		public  synchronized SteamedBun pop() {
			//何时消费 容器中是否存在数据
			if(count==0) {
				try {
					this.wait();//线程阻塞,生产者通知消费就可以解除
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			  //存在数据消费
			count--;
			SteamedBun bun=buns[count];
			this.notifyAll();//存在空间可以唤醒生产
			return bun;
			
		}
		
}
class SteamedBun{
	int id;

	public SteamedBun(int id) {
		super();
		this.id = id;
	}
	
}
public class CoTest1 {
public static void main(String[] args) {
	SynContainer container=new SynContainer();
	new  Producter(container).start();
	new Comsumer(container).start();
}
}

      2.信号灯法 

package cn.zwl.cooperation;
/**
 * 
 * 
 * 信号灯法:借助标志位
 * @author dell
 *生产者 演员
 *消费者 观众
 *同一个资源 电视
 */
public class CoTest2 {
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) {
		super();
		this.tv = tv;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		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) {
		super();
		this.tv = tv;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		for (int i = 0; i <20; i++) {
			this.tv.watch();
		}
	}
}
class Tv{
	String voice;
	//信号灯:T表示演员表演 观众等待;F表示观众观看 演员等待
	boolean flag=true;
	
	//表演
	public synchronized void play(String voice) {
		// TODO Auto-generated method stub
		//演员等待
		if (!flag) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//表演
		System.out.println("表演了:"+voice);
        this.voice=voice;
        //表演完了,唤醒等待线程
        this.notifyAll();
        this.flag=!this.flag;
	}
	public synchronized void watch() {
		// TODO Auto-generated method stub
		//观众等待
		if (flag) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//观众观看
       System.out.println("听到了:"+voice);
       //看完了,唤醒等待的线程并切换标志
       this.notifyAll();
       this.flag=!this.flag;
	}
}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值