使用Condition的生產者消費者模式

1.生產者消費者在處理併發時是很常用的處理方式 是很有必要掌握的。
2.Lock其實就相當於傳統的synchronize Condition的await()相當於wait() signal()相當於notify().
3.沒有使用傳統的 wait() 和notify()的原因是 Condition可以有多個,能夠用來解決更加複雜的情況.
直接上代碼:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConsumerAndProducter {

	public static void main(String[] args) {
		new ConsumerAndProducter().work();
	}

	int length = 8;// 倉庫最大容量

	Lock lock = new ReentrantLock();
	Condition notFull = lock.newCondition();
	Condition notEmpty = lock.newCondition();

	List<Productor> Productors = new ArrayList<>();

	private void work() {
		new Thread(new Runnable() {
			public void run() {
				consume();
			}
		}).start();
		

		new Thread(new Runnable() {
			public void run() {
				consume();
			}
		}).start();
		

		new Thread(new Runnable() {
			public void run() {
				product();
			}
		}).start();
		
	}

	/**
	 * 消費
	 */
	private void consume() {

		while (true) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e1) {
				
				e1.printStackTrace();
			}
			
			lock.lock();
			try {
				while (Productors.size() == 0) {
					System.out.println("容器爲空 等待生產"+Thread.currentThread().getName());
					notEmpty.await();
				}
				Productors.remove(0);
				System.out.println("消費了一個產品"+Thread.currentThread().getName());
				System.out.println("容器有空餘 通知生產"+Thread.currentThread().getName());
				notFull.signal();

			} catch (InterruptedException e) {

				e.printStackTrace();
			} finally {
				lock.unlock();
			}
		}

	}

	/**
	 * 生產
	 */
	private void product() {
		while(true){
			try {
				Thread.sleep(500); //生產效率
			} catch (InterruptedException e1) {
				
				e1.printStackTrace();
			}
			
			
			lock.lock();
			try {
				while (Productors.size() == 8) {
					System.out.println("容器已滿 等待消費"+Thread.currentThread().getName());
					notFull.await();
				}

				Productors.add(new Productor()); //生產機器數
				
				System.out.println("產品已生產 通知可以消費"+Thread.currentThread().getName());
				notEmpty.signal();

			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
				lock.unlock();
			}
		}
		
	}

	/**
	 * 產品
	 * @author z2wenfa
	 *
	 */
	private class Productor {

		public Productor() {
		}

	}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章