java wait()/notify() 实现生产者消费者模式

java中的多线程会涉及到线程间通信,常见的线程通信方式,例如共享变量、管道流等,这里我们要实现生产者消费者模式,也需要涉及到线程通信,不过这里我们用到了java中的wait()、notify()方法:

wait():进入临界区的线程在运行到一部分后,发现进行后面的任务所需的资源还没有准备充分,所以调用wait()方法,让线程阻塞,等待资源,同时释放临界区的锁,此时线程的状态也从RUNNABLE状态变为WAITING状态;

notify():准备资源的线程在准备好资源后,调用notify()方法通知需要使用资源的线程,同时释放临界区的锁,将临界区的锁交给使用资源的线程。

wait()、notify()这两个方法,都必须要在临界区中调用,即是在synchronized同步块中调用,不然会抛出IllegalMonitorStateException的异常。

实现源码:

生产者线程类:

package threads;

import java.util.List;
import java.util.UUID;

public class Producer extends Thread{

	private List<String> storage;//生产者仓库
	public Producer(List<String> storage) {
		this.storage = storage;
	}
	public void run(){
		//生产者每隔1s生产1~100消息
		long oldTime = System.currentTimeMillis();
		while(true){
			synchronized(storage){
				if (System.currentTimeMillis() - oldTime >= 1000) {
					oldTime = System.currentTimeMillis();
					int size = (int)(Math.random()*100) + 1;
					for (int i = 0; i < size; i++) {
						String msg = UUID.randomUUID().toString();
						storage.add(msg);
					}
					System.out.println("线程"+this.getName()+"生产消息"+size+"条");
					storage.notify();
				}
			}
		}
	}
}

消费者线程类:

package threads;

import java.util.List;

public class Consumer extends Thread{

	private List<String> storage;//仓库
	public Consumer(List<String> storage) {
		this.storage = storage;
	}
	public void run(){
		while(true){
			synchronized(storage){
				//消费者去仓库拿消息的时候,如果发现仓库数据为空,则等待
				if (storage.isEmpty()) {
					try {
						storage.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				int size = storage.size();
				for (int i = size - 1; i >= 0; i--) {
					storage.remove(i);
				}
				System.out.println("线程"+this.getName()+"成功消费"+size+"条消息");
			}
		}
	}
}

仓库类:

package threads;

import java.util.ArrayList;
import java.util.List;

public class Storage {

	private List<String> storage;//生产者和消费者共享的仓库
	public Storage() {
		storage = new ArrayList<String>();
	}
	public List<String> getStorage() {
		return storage;
	}
	public void setStorage(List<String> storage) {
		this.storage = storage;
	}
	
}

main方法类:

package threads;

public class App {

	public static void main(String[] args) {
		Storage storage = new Storage();
		Producer producer = new Producer(storage.getStorage());
		Consumer consumer = new Consumer(storage.getStorage());
		producer.start();
		consumer.start();
	}
}

生产消费效果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值