生产者与消费者

本文通过Java代码详细解释了生产者消费者模型的概念,展示了使用`synchronized`关键字和`wait()`、`notify()`方法实现的线程同步例子。在示例中,生产者线程不断生产窝头并放入篮子,消费者线程则从篮子中取出并消费窝头,实现了资源的共享和有效利用。此外,还提供了一个基于`LinkedList`的存储和消费产品的例子,同样利用了线程同步来避免数据竞争问题。
摘要由CSDN通过智能技术生成

生产者与消费者的理解

简单说就是一个类甚至多个类负责生产,同理消费者也是如此。

举例来说,一个变量,生产者不断增加;消费者不断减少。不论是在实际生活当中还是互联网应用当中都是如此,比如12306抢票、包子铺做包卖包、银行存取转账等。

代码如下:

1)

public class ProducerConsumer {

	public static void main(String[] args) {
		SyncStack ss=new SyncStack();
		Producer p=new Producer(ss);
		Consumer c=new Consumer(ss);
		new Thread(p).start();
		new Thread(c).start();
	}
}
class WoTou{
	int id;//给每个窝头作个记号
	public WoTou(int id) {
		this.id = id;
	}
	@Override
	public String toString() {
		return "WoTou :" + id ;
	}
}
class SyncStack {//篮子类
	int index = 0;
	WoTou[] arrWT=new WoTou[6];//篮子容量为6
	
	public synchronized void push(WoTou wt){//往里增加窝头的方法
		while(index==arrWT.length){
			/*篮子装满了就执行wait等待,如果这里使用if执行完try语句就会跳出if
			 * 然后执行notify语句叫醒,接着往装满的篮子继续装包子就会出现数组下标越界异常*/
			try{
				this.wait();//不是当前线程wait而是当前访问的这个线程wait
			}catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notify();//一般wait方法与notify互相对应:wait负责等待,notify负责叫醒
		arrWT[index]=wt;//将传进来的窝头赋值给arrWT数组下标
		index++;//每次+1
		//synchronized保证多个线程添加窝头的时候能数据一致
	}
	public synchronized WoTou pop(){//往外拿窝头的方法
		while(index==0){//
			try{
				this.wait();
			}catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notify();
		index--;
		return arrWT[index];
	}
}
class Producer implements Runnable{//生产类
	SyncStack ss=null;//设置初始值篮子为空
	
	public Producer(SyncStack ss) {
	this.ss = ss;
	//然后把局部变量传递给成员变量,即将做好的窝头放在篮子里
}

	@Override
	public void run() {
		for(int i=0;i<20;i++){
			WoTou wt=new WoTou(i);
			ss.push(wt);
			//将生产的窝头使用push方法增加实现
			System.out.println("生产了:"+ wt);
			try {
				Thread.sleep((int)(Math.random()*1000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class Consumer implements Runnable{//消费类
	SyncStack ss=null;
	
	public Consumer (SyncStack ss) {
	this.ss = ss;
}

	@Override
	public void run() {
		for(int i=0;i<20;i++){
			WoTou wt=ss.pop();
			System.out.println("消费了:"+ wt);
			try {
				Thread.sleep((int)(Math.random()*1000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

运行结果如下:

生产了:WoTou :0
消费了:WoTou :0
生产了:WoTou :1
消费了:WoTou :1
生产了:WoTou :2
消费了:WoTou :2
生产了:WoTou :3
消费了:WoTou :3
生产了:WoTou :4
消费了:WoTou :4
生产了:WoTou :5
消费了:WoTou :5
生产了:WoTou :6
消费了:WoTou :6
生产了:WoTou :7
生产了:WoTou :8
消费了:WoTou :8
生产了:WoTou :9
生产了:WoTou :10
消费了:WoTou :10
生产了:WoTou :11
消费了:WoTou :11
生产了:WoTou :12
生产了:WoTou :13
消费了:WoTou :13
生产了:WoTou :14
消费了:WoTou :14
生产了:WoTou :15
消费了:WoTou :15
生产了:WoTou :16
消费了:WoTou :16
生产了:WoTou :17
消费了:WoTou :17
生产了:WoTou :18
消费了:WoTou :18
生产了:WoTou :19
消费了:WoTou :19
消费了:WoTou :12
消费了:WoTou :9
消费了:WoTou :7

 

2)

import java.util.LinkedList;
import java.util.Random;

public class Test {

	public static void main(String[] args) {
		Mystorage ss=new Mystorage();
		Producer p=new Producer(ss);
		Consumer c=new Consumer(ss);
		new Thread(p).start();
		new Thread(c).start();
	}

}
class Mystorage{
	LinkedList<Object> list=new LinkedList<>();
	
	static final int MAX_CAPACITY=100;

	public synchronized void store(String product){
		while(list.size()>MAX_CAPACITY){
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		list.offer(product);
		System.out.println(Thread.currentThread().getName()+"\t存储了:"+product);
		notify();
	}
	
	public  synchronized void take(){
		while(list.size()==0){
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		Object product=list.poll();
		System.out.println(Thread.currentThread().getName()+"\t消费了:"+product);
		notify();
	}
}
class Producer implements Runnable{
	Mystorage storag=new Mystorage();
	
	
	public Producer(Mystorage storag) {
		super();
		this.storag = storag;
	}


	@Override
	public void run() {
		for(int i=1;i<10;i++){
			String product="产品编号:"+new Random().nextInt(10);
			storag.store(product);
		}
	}
}
class Consumer implements Runnable{
	Mystorage storag=new Mystorage();
	
	
	public Consumer(Mystorage storag) {
		super();
		this.storag = storag;
	}


	@Override
	public void run() {
		for(int i=1;i<10;i++){
			String product="产品编号:"+new Random().nextInt(10);
			storag.take();
		}
	}
}

运行结果如下:

Thread-0	存储了:产品编号:1
Thread-1	消费了:产品编号:1
Thread-0	存储了:产品编号:0
Thread-0	存储了:产品编号:4
Thread-0	存储了:产品编号:0
Thread-0	存储了:产品编号:8
Thread-0	存储了:产品编号:7
Thread-0	存储了:产品编号:2
Thread-1	消费了:产品编号:0
Thread-0	存储了:产品编号:6
Thread-1	消费了:产品编号:4
Thread-0	存储了:产品编号:9
Thread-1	消费了:产品编号:0
Thread-1	消费了:产品编号:8
Thread-1	消费了:产品编号:7
Thread-1	消费了:产品编号:2
Thread-1	消费了:产品编号:6
Thread-1	消费了:产品编号:9

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值