生产者和消费者模式
三个对象、生产者、消费者、商品库存
商品库存是共享的 共享的数据要进行线程同步安全保护
默认商品的数量为0,程序执行
1、生产者生成10个商品然后停止生成。释放商品库存锁 (Object.wait())
2、消费者依次消费10个商品然后停止消费、释放商品锁(Object.wait())、唤醒生成者生成(Object.notifyAll())
3、生产者生成10个商品然后停止生成。释放商品库存锁(Object.wait())、唤醒消费者消费(Object.notifyAll())
依次循环2、3步骤
两者在每次消费和生成完成后都唤醒进入阻塞状态的线程、让其进入就绪状态、让后它会运行、遇到synchronized进入锁池
等上一个线程结束拿到锁然后运行 如此循环
总体代码
package com.it.thread;
/**
* @author yeah
* @date 2020/5/25 20:02
*/
public class WaitThread {
public static void main(String[] args) {
// 一个商品 采用的时对象锁 所以就一把锁
Repository repository = new Repository();
// 两个线程共享一个对象
Thread thread1 = new Thread(new Producer(repository));
Thread thread2 = new Thread(new Consumer(repository));
thread1.start();
// 确保让生产者先执行 如果没有也可以
// 消费者检测到没有会让生成者 从锁池进入到就绪状态再到运行状态然后添加一个商品后释放所有与商品库存阻塞的线程、
// 直到生产者执行wait()释放锁
try {
Thread.sleep(1000*3);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread2.start();
}
}
class Producer implements Runnable{
private Repository repository;
public Producer(Repository repository) {
this.repository = repository;
}
@Override
public void run() {
while (true){
synchronized (repository){
// 如果库存大于5就释放锁然后进入阻塞状态等待被消费者唤醒
if (repository.getRepertory()>=5){
try {
repository.wait();
}catch (Exception e){
e.printStackTrace();
}
}
else{
repository.AddRepertory();
try {
Thread.sleep(1000*1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("repertory+1 currentRepertory="+repository.getRepertory());
// TODO 2 唤醒消费者消费 当消费者第一轮消费完成的时候 消费者唤醒了生成者、而自己却进入了阻塞状态、这时候就需要奥生产者来唤醒
repository.notifyAll();
}
}
}
}
}
class Consumer implements Runnable{
private Repository repository;
public Consumer(Repository repository) {
this.repository = repository;
}
@Override
public void run() {
while (true) {
synchronized (repository) {
// 商品小于等于0 消费者进入阻塞状态 生产者会拿到锁 然后添加一个商品并且释放被阻塞的线程、然后生消费者进入锁池
if (repository.getRepertory() <= 0) {
try {
repository.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
repository.reduceRepertory();
try {
Thread.sleep(1000*1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("reduceRepertory-1 CurrentRepertory=" + repository.getRepertory());
//TODO 1 唤醒生产者生成 因为生产者跳转到消费者的时候 已经进入阻塞状态了 不唤醒就无法跳转到生产者
repository.notifyAll();
}
}
}
}
}
class Repository{
private Integer repertory;
public Repository() {
this.repertory = 0;
}
public void setRepertory(Integer repertory) {
this.repertory = repertory;
}
public Integer getRepertory() {
return repertory;
}
public void AddRepertory(){
repertory += 1;
}
public void reduceRepertory(){
repertory -= 1;
}
}
执行结果