使用线程模拟企业的生产者和消费者

574 篇文章 4 订阅
272 篇文章 1 订阅

测试类:
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();
}

}

/**

  • 仓库类
  • @author Administrator

*/
import java.util.LinkedList;

public class MyStorage {
LinkedList 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) {
		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 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。
	*/
}

}
/**

  • 生产者线程
  • @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();
	}
}

}

/**

  • 消费者线程
  • @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();
	}
}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值