Java 线程多线程编程3---线程同步之生产者与消费者问题

7 篇文章 0 订阅
5 篇文章 0 订阅

生产者与消费者问题:

第一步:把架子搭起来

package com.zhj.www;

public class ProceduerConsumer {
	
	public static void main(String[] args) {
		
	}
}

//馒头实体
class wotou{
	int id;
	wotou(int id) {
		this.id = id;
	}
	public String toString() {
	 return "wotou : "+id;
	}
	
}	
//馒头栈
class syncStack{
	int index = 0;
	wotou[] arrWT= new wotou[6];//这个容器只能装6个馒头
	syncStack(int index) {
		this.index = index;
	}
	//往里仍馒头,之所以使用synchronized关键字,是因为防止多个人同时往里扔,
	public synchronized void push(wotou wt) {
		 arrWT[index] = wt;    /*这两行不能分开
		 index++;               */
	}
	//从里面取馒头,拿最上面的那一个
	public synchronized wotou pop() {
		 index--;
		 return arrWT[index];
	}
	 
}
/*多个生产者,也就是多个线程同时在执行*/
//生产者,用于对馒头栈的引用,他需要知道生产完馒头,需要往哪个筐里仍馒头
class proceduer implements Runnable{
	syncStack  ss= null;
	proceduer(syncStack ss) {
		this.ss = ss;
	}
	/*run方法对应着生产过程*/
	public void run() {
		for(int i =0;i<20;i++) {
			wotou wt = new wotou(i);
			ss.push(wt);
		}
	}
}
//消费者
class consumer implements Runnable{
	syncStack  ss= null;
	consumer(syncStack ss) {
		this.ss = ss;
	}
	public void run() {
		for(int i =0;i<20;i++) {
			wotou wotou  =ss.pop();
			System.out.println(wotou);
		}
	}
}

第二步:

需要考虑当馒头筐满了怎么办?马上就会报错?在push方法里考虑,让这个线程休息一下;

wait方法来源于object;wait的时候这把锁也就不属于我了。但是sleep的时候我仍然抓住这把锁。

package com.zhj.www;

import java.io.IOException;

public class ProceduerConsumer {
	
	public static void main(String[] args) {
		syncStack ss = new syncStack();
		proceduer proceduer = new proceduer(ss);
		consumer consumer  = new consumer(ss);
		new Thread(proceduer).start();
		new Thread(consumer).start();
		
	}
}

//馒头实体
class wotou{
	int id;
	wotou(int id) {
		this.id = id;
	}
	public String toString() {
	 return "wotou : "+id;
	}
	
}	
//馒头栈
class syncStack{
	int index = 0;
	wotou[] arrWT= new wotou[6];//这个容器只能装6个馒头
	
	//往里仍馒头,之所以使用synchronized关键字,是因为防止多个人同时往里扔,
	public synchronized void push(wotou wt)  {
		if(index == arrWT.length){
			try {
				 this.wait();//当前对象正在执行push方法需要wait
			 }catch (InterruptedException e) {
			 e.printStackTrace();
			 }
		}
		this.notify();//哪个线程在等待就唤醒哪个线程
		 arrWT[index] = wt;    /*这两行不能分开*/
	     index++;                
	}
	
	//从里面取馒头,拿最上面的那一个
	public synchronized wotou pop() {
		if(index == 0) {
			try {
				this.wait();
			}
			catch (InterruptedException e) {
			e.printStackTrace();
			}
		}
		this.notify();//object类里的方法,唤醒一个;
		index--;
		return arrWT[index];
		
		
	}
	 
}
/*多个生产者,也就是多个线程同时在执行*/
//生产者,用于对馒头栈的引用,他需要知道生产完馒头,需要往哪个筐里仍馒头
class proceduer implements Runnable{
	syncStack  ss= null;
	proceduer(syncStack ss) {
		this.ss = ss;
	}
	/*run方法对应着生产过程*/
	public void run() {
		for(int i =0;i<20;i++) {
			wotou wt = new wotou(i);
			ss.push(wt);
			System.out.println("生产了:"+wt);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
//消费者
class consumer implements Runnable{
	syncStack  ss= null;
	consumer(syncStack ss) {
		this.ss = ss;
	}
	public void run() {
		for(int i =0;i<20;i++) {
			wotou wotou  =ss.pop();
			System.out.println("消费了:"+wotou);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

运行过程:


可以发现生产一个馒头,就消耗一个馒头。

完善之后的栗子:

package com.zhj.www;

import java.io.IOException;

public class ProceduerConsumer {
	
	public static void main(String[] args) {
		syncStack ss = new syncStack();
		proceduer proceduer = new proceduer(ss);
		consumer consumer  = new consumer(ss);
		new Thread(proceduer).start();
		
		new Thread(consumer).start();
		
		
		
	}
}

//馒头实体
class wotou{
	int id;
	wotou(int id) {
		this.id = id;
	}
	public String toString() {
	 return "wotou : "+id;
	}
	
}	
//馒头栈
class syncStack{
	int index = 0;
	wotou[] arrWT= new wotou[6];//这个容器只能装6个馒头
	
	//往里仍馒头,之所以使用synchronized关键字,是因为防止多个人同时往里扔,
	public synchronized void push(wotou wt)  {
		while(index == arrWT.length){
			try {
				 this.wait();//当前对象正在执行push方法需要wait
			 }catch (InterruptedException e) {
				 e.printStackTrace();
			 }
		}
		this.notify();//哪个线程在等待就唤醒哪个线程
		 arrWT[index] = wt; /*这两行不能分开*/
	     index++;                
	}
	
	//从里面取馒头,拿最上面的那一个
	public synchronized wotou pop() {
		while(index == 0) {
			try {
				this.wait();
			}
			catch (InterruptedException e) {
			e.printStackTrace();
			}
		}
		this.notify();//object类里的方法,唤醒一个;	
		index--;
		return arrWT[index];
	}
	 
}
/*多个生产者,也就是多个线程同时在执行*/
//生产者,用于对馒头栈的引用,他需要知道生产完馒头,需要往哪个筐里仍馒头
class proceduer implements Runnable{
	syncStack  ss= null;
	proceduer(syncStack ss) {
		this.ss = ss;
	}
	/*run方法对应着生产过程*/
	public void run() {
		for(int i =0;i<20;i++) {
			wotou wt = new wotou(i);
			ss.push(wt);
			System.out.println("生产了:"+wt);
			try {
				Thread.sleep((int)(Math.random()*200));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
//消费者
class consumer implements Runnable{
	syncStack  ss= null;
	consumer(syncStack ss) {
		this.ss = ss;
	}
	public void run() {
		for(int i =0;i<20;i++) {
			wotou wotou  =ss.pop();
			System.out.println("消费了:"+wotou);
			try {
				Thread.sleep((int)(Math.random()*1000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

运行之后。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值