java多线程之生产者消费者模型

生产者-消费者模型

生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。

解决方法就是一个线程负责生产数据,放到共享区域,然后通知另一个线程去消耗数据。如果没有wait()和notify(),消费者线程就要不停去检查是否有数据被产生。

代码如下:

package produce_consume;

import java.util.*;
import java.util.List;

import thread_test.test1;

class Resource{
	//生产上限
	final int MAX = 10;
	List<String> list = new LinkedList<String>();
	
	public synchronized void produce(){
		while (list.size() > MAX) {
			System.out.println("生产过剩,等待消费");
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		list.add("资源");
		System.out.println("正在生产");
		notify();
	}
	
	public synchronized void consume(){
		while (list.size() <= 0) {
			System.out.println("生产不足,等待生产");
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		list.remove(0);
		System.out.println("正在消费");
		notify();
	}
}

class MyThread implements Runnable{
	String name;
	Resource resource;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public MyThread(String name,Resource resource){
		this.name = name;
		this.resource = resource;
	}
	@Override
	public void run() {
		
		if (this.name.equals("生产者")) {
			
			resource.produce();
		}
		if (this.name.equals("消费者")) {
			
			resource.consume();
		}
	}
	
}
public class Test {
	public static void main(String[] args) {
		Resource resource = new Resource();
		while (true) {
			Thread t1 = new Thread(new MyThread("消费者",resource));
			t1.start();
			
			Thread t2 = new Thread(new MyThread("生产者",resource));
			t2.start();
			
			
		}
		
	}
}

需要注意的几点是

1. 要在synchronized的函数或对象里使用wait、notify和notifyAll,不然Java虚拟机会生成 IllegalMonitorStateException。

2. 要在while循环里而不是if语句下使用wait。这样,循环会在线程睡眠前后都检查wait的条件,并在条件实际上并未改变的情况下处理唤醒通知。

3. 要在多线程间共享的对象(在生产者消费者模型里即缓冲区队列)上使用wait。

猜你喜欢

转载自blog.csdn.net/wanderlustlee/article/details/79667833