java基础回顾之线程-模拟生产者与消费者(生产者消费者模式)

574 篇文章 4 订阅

在这里插入图片描述

package com.bjpowernode.demo01;
/**
 * 仓库类
 * @author Administrator
 *
 */
import java.util.LinkedList;

public class MyStorage {
	LinkedList<Object> list = new LinkedList<>(); 	//存储产品 
	private static final int MAX_CAPACITY = 100; 	//仓库的最大容量
	
	//存储产品 ,约定每次存10个产品 
	public synchronized void store() {
		//仓库已满 ,生产者等待,等到消费者消费了后再继续生产
		while ( list.size() >= MAX_CAPACITY) {
			try {
				this.wait();  	//wait()/notify()只能在同步代码块中由锁对象调用
				//执行wait(),线程等待,会释放锁对象,
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		System.out.println( Thread.currentThread().getName() + "存储产品 前, 仓库容量:" + list.size());
		for( int i =1; i <= 10;i++){
			//offer属于 offer in interface Deque<E>,add 属于 add in interface Collection<E>。

			//当队列为空时候,使用add方法会报错,而offer方法会返回false。都是添加

			//作为List使用时,一般采用add / get方法来 压入/获取对象。

			//作为Queue使用时,才会采用 offer/poll/take等方法作为链表对象时,offer等方法相对来说没有什么意义这些方法是用于支持队列应用的。
			list.offer(new Object());
		}
		System.out.println( Thread.currentThread().getName() + "存了10个产品后, 仓库容量:" + list.size());
		//通知消费者消费
		this.notify();
	}
	
	//取产品 , 约定一次取10个
	public synchronized void get() {
		//判断仓库如果已空, 消费者需要等待, 等待生产者生产了产品后再继续消费
		while ( list.size() <= 0) { //不用if用while的原因是防止假唤醒
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		System.out.println( Thread.currentThread().getName() + "消费 前, 仓库容量:" + list.size());
		for( int i =1; i <= 10;i++){
			//poll是减少的意思
			list.poll();
		}
		System.out.println( Thread.currentThread().getName() + "消费了10个产品 后, 仓库容量:" + list.size());
		//通知生产者生产
		this.notifyAll();

		/*notify和notifyAll的区别

		如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。
		当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争
		优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。
		*/
	}
}

package com.bjpowernode.demo01;
/**
 * 生产者线程
 * @author Administrator
 *
 */
public class Producer extends Thread {
	MyStorage storage;
	
	public Producer(MyStorage storage) {
		super();
		this.storage = storage;
	}

	@Override
	public void run() {
		//
		for(int d = 1; d <= 200; d++){
			storage.store();
		}
	}
}

package com.bjpowernode.demo01;
/**
 * 消费者线程
 * @author Administrator
 *
 */
public class Consumer extends Thread {
	MyStorage storage;
	
	public Consumer(MyStorage storage) {
		super();
		this.storage = storage;
	}

	@Override
	public void run() {
		//
		for(int d = 1; d <= 200; d++){
			storage.get();
		}
	}
}

package com.bjpowernode.demo01;
/**
 * 使用线程模拟企业的生产者和消费者
 * @author Administrator
 *
 */
public class Test01 {

	public static void main(String[] args) {
		MyStorage storage = new MyStorage();
		
		Producer producer = new Producer(storage);
		Consumer consumer = new Consumer(storage);
		producer.setName("生产者");
		consumer.setName("销售人员");
		
		producer.start();
		consumer.start();
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值