关闭

今天在学习线程的时候接触到消费者和生产者模式,写了简单的代码

标签: java线程
49人阅读 评论(0) 收藏 举报
分类:
package javaluange2;

import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConsumerProducer {

	private static Buffer buffer = new Buffer();

	public static void main(String[] args) {
		ExecutorService executor = Executors.newFixedThreadPool(2);
		executor.execute(new ProducerTask());
		executor.execute(new ConsumerTask());
		executor.shutdown();
	}

	/**
	 * 生产者
	 * 
	 * @author baqy
	 *
	 */
	private static class ProducerTask implements Runnable {

		@Override
		public void run() {
			try {
				int i = 1;
				while (true) {
					System.out.println("\t\tProducer writes " + i);
					buffer.write(i++);
					Thread.sleep((int) (Math.random() * 10000) );
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 * 消费者
	 * 
	 * @author baqy
	 *
	 */
	private static class ConsumerTask implements Runnable {

		@Override
		public void run() {
			try {
				while (true) {
					System.out.println("\t\tConsumer reads " + buffer.read());
					Thread.sleep((int) (Math.random() * 10) + 1);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}

	private static class Buffer {
		private static final int CAPACITY = 1;
		private LinkedList<Integer> queue = new LinkedList<Integer>();
		private static Lock lock = new ReentrantLock();// create a lock
		// create two conditions
		private static Condition NotEmpty = lock.newCondition();
		private static Condition NotFull = lock.newCondition();

		public int read() {
			int value=0;
			lock.lock();
			try {
				//当队列中为空时等待
				while (queue.isEmpty()) {
						System.out.print("wait for notEmpty condition");
						NotEmpty.await();
				}
				//不为空的时候读取对首元素
				value= queue.remove();
				NotFull.signal();//唤醒notFull 条件
			} catch (InterruptedException e) {
				e.printStackTrace();
			}finally {
				lock.unlock();
				return value;
			}
			
		}

		public void write(int value) {
			lock.lock();
			try {
				while (queue.size() == CAPACITY) {// 容量已满
					System.out.print("\t\twait for not full condition");
					NotFull.await();
				}
				//容量不满时在队列中添加到队尾
				queue.offer(value);
				//唤醒notEmpty 条件
				NotEmpty.signal();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}finally {
				lock.unlock();
			}
		}

	}
}

这个例子假设缓冲区存储整数,大小也是受限的,缓冲区提供了write(),read(),在写入缓冲区的时候判断大小是否已经满了,就让线程处于等待,消费也是判断缓冲区是否为空,空就等待。这就是两个条件,通过Lock创建出来的,队列是用链表生成的,在队尾生产,队首消费,在满足添加之后唤醒消费者,消费者也是一样,消费完了唤醒生产者。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2119次
    • 积分:118
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类