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();
}
}
生产消费效果: