您的位置:首页 > 编程语言

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

2016-08-28 22:26 447 查看
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创建出来的,队列是用链表生成的,在队尾生产,队首消费,在满足添加之后唤醒消费者,消费者也是一样,消费完了唤醒生产者。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 线程