线程之生产者消费者模型
2015-08-10 09:58
489 查看
生产者消费者问题是线程模型中经典的问题,生产者和消费者子在同一时间段内共用同一个存储空间,生产者向空间存储数据,而消费者取用数据,如果不加以协调可能出现以下情况:
存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间添加产品。互相等待,发生死锁。
java解决线程模型的三种方式
1、wait()和notify()
import java.util.LinkedList;
public class ProducerConsumer {
private LinkedList<Object> storeHouse = new LinkedList<Object>();
private int MAX = 10;
public ProducerConsumer() {
}
public void start() {
new Producer().start();
new Comsumer().start();
}
class Producer extends Thread {
public void run() {
while (true) {
synchronized (storeHouse) {
try {
while (storeHouse.size() == MAX) {
System.out.println("storeHouse is full , please wait");
storeHouse.wait();
}
Object newOb = new Object();
if (storeHouse.add(newOb)) {
System.out.println("Producer put a Object to storeHouse");
Thread.sleep((long) (Math.random() * 3000));
storeHouse.notify();
}
} catch (InterruptedException ie) {
System.out.println("producer is interrupted!");
}
}
}
}
}
class Comsumer extends Thread {
public void run() {
while (true) {
synchronized (storeHouse) {
try {
while (storeHouse.size() == 0) {
System.out.println("storeHouse is empty , please wait");
storeHouse.wait();
}
storeHouse.removeLast();
System.out.println("Comsumer get a Object from storeHouse");
Thread.sleep((long) (Math.random() * 3000));
storeHouse.notify();
} catch (InterruptedException ie) {
System.out.println("Consumer is interrupted");
}
}
}
}
}
public static void main(String[] args) throws Exception {
ProducerConsumer pc = new ProducerConsumer();
pc.start();
}
}
2、await()和signal(),即线程锁的方式
package sort;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ProducerConsumer {
private LinkedList<Object> myList = new LinkedList<Object>();
private int MAX = 10;
private final Lock lock = new ReentrantLock();
private final Condition full = lock.newCondition();
private final Condition empty = lock.newCondition();
public ProducerConsumer() {
}
public void start() {
new Producer().start();
new Consumer().start();
}
public static void main(String[] args) throws Exception {
ProducerConsumer s2 = new ProducerConsumer();
s2.start();
}
class Producer extends Thread {
public void run() {
while (true) {
lock.lock();
try {
while (myList.size() == MAX) {
System.out.println("warning: it's full!");
full.await();
}
Object o = new Object();
if (myList.add(o)) {
System.out.println("Producer: " + o);
empty.signal();
}
} catch (InterruptedException ie) {
System.out.println("producer is interrupted!");
} finally {
lock.unlock();
}
}
}
}
class Consumer extends Thread {
public void run() {
while (true) {
lock.lock();
try {
while (myList.size() == 0) {
System.out.println("warning: it's empty!");
empty.await();
}
Object o = myList.removeLast();
System.out.println("Consumer: " + o);
full.signal();
} catch (InterruptedException ie) {
System.out.println("consumer is interrupted!");
} finally {
lock.unlock();
}
}
}
}
}
3、阻塞队列的方式
import java.util.concurrent.*;
public class ProducerConsumer {
// 建立一个阻塞队列
private LinkedBlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(10);
public ProducerConsumer() {
}
public void start() {
new Producer().start();
new Consumer().start();
}
public static void main(String[] args) throws Exception {
ProducerConsumer s3 = new ProducerConsumer();
s3.start();
}
class Producer extends Thread {
public void run() {
while (true) {
try {
Object o = new Object();
// 取出一个对象
queue.put(o);
System.out.println("Producer: " + o);
} catch (InterruptedException e) {
System.out.println("producer is interrupted!");
}
// }
}
}
}
class Consumer extends Thread {
public void run() {
while (true) {
try {
// 取出一个对象
Object o = queue.take();
System.out.println("Consumer: " + o);
} catch (InterruptedException e) {
System.out.println("producer is interrupted!");
}
// }
}
}
}
}
总结:
三种方式原理一致,都是对独立空间进行加锁,阻塞和唤醒线程,第一种方式比较传统,第三种方式最简单,只需存储和取用,线程同步的操作交由LinkedBlockingQueue全权处理。
存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间添加产品。互相等待,发生死锁。
java解决线程模型的三种方式
1、wait()和notify()
import java.util.LinkedList;
public class ProducerConsumer {
private LinkedList<Object> storeHouse = new LinkedList<Object>();
private int MAX = 10;
public ProducerConsumer() {
}
public void start() {
new Producer().start();
new Comsumer().start();
}
class Producer extends Thread {
public void run() {
while (true) {
synchronized (storeHouse) {
try {
while (storeHouse.size() == MAX) {
System.out.println("storeHouse is full , please wait");
storeHouse.wait();
}
Object newOb = new Object();
if (storeHouse.add(newOb)) {
System.out.println("Producer put a Object to storeHouse");
Thread.sleep((long) (Math.random() * 3000));
storeHouse.notify();
}
} catch (InterruptedException ie) {
System.out.println("producer is interrupted!");
}
}
}
}
}
class Comsumer extends Thread {
public void run() {
while (true) {
synchronized (storeHouse) {
try {
while (storeHouse.size() == 0) {
System.out.println("storeHouse is empty , please wait");
storeHouse.wait();
}
storeHouse.removeLast();
System.out.println("Comsumer get a Object from storeHouse");
Thread.sleep((long) (Math.random() * 3000));
storeHouse.notify();
} catch (InterruptedException ie) {
System.out.println("Consumer is interrupted");
}
}
}
}
}
public static void main(String[] args) throws Exception {
ProducerConsumer pc = new ProducerConsumer();
pc.start();
}
}
2、await()和signal(),即线程锁的方式
package sort;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ProducerConsumer {
private LinkedList<Object> myList = new LinkedList<Object>();
private int MAX = 10;
private final Lock lock = new ReentrantLock();
private final Condition full = lock.newCondition();
private final Condition empty = lock.newCondition();
public ProducerConsumer() {
}
public void start() {
new Producer().start();
new Consumer().start();
}
public static void main(String[] args) throws Exception {
ProducerConsumer s2 = new ProducerConsumer();
s2.start();
}
class Producer extends Thread {
public void run() {
while (true) {
lock.lock();
try {
while (myList.size() == MAX) {
System.out.println("warning: it's full!");
full.await();
}
Object o = new Object();
if (myList.add(o)) {
System.out.println("Producer: " + o);
empty.signal();
}
} catch (InterruptedException ie) {
System.out.println("producer is interrupted!");
} finally {
lock.unlock();
}
}
}
}
class Consumer extends Thread {
public void run() {
while (true) {
lock.lock();
try {
while (myList.size() == 0) {
System.out.println("warning: it's empty!");
empty.await();
}
Object o = myList.removeLast();
System.out.println("Consumer: " + o);
full.signal();
} catch (InterruptedException ie) {
System.out.println("consumer is interrupted!");
} finally {
lock.unlock();
}
}
}
}
}
3、阻塞队列的方式
import java.util.concurrent.*;
public class ProducerConsumer {
// 建立一个阻塞队列
private LinkedBlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(10);
public ProducerConsumer() {
}
public void start() {
new Producer().start();
new Consumer().start();
}
public static void main(String[] args) throws Exception {
ProducerConsumer s3 = new ProducerConsumer();
s3.start();
}
class Producer extends Thread {
public void run() {
while (true) {
try {
Object o = new Object();
// 取出一个对象
queue.put(o);
System.out.println("Producer: " + o);
} catch (InterruptedException e) {
System.out.println("producer is interrupted!");
}
// }
}
}
}
class Consumer extends Thread {
public void run() {
while (true) {
try {
// 取出一个对象
Object o = queue.take();
System.out.println("Consumer: " + o);
} catch (InterruptedException e) {
System.out.println("producer is interrupted!");
}
// }
}
}
}
}
总结:
三种方式原理一致,都是对独立空间进行加锁,阻塞和唤醒线程,第一种方式比较传统,第三种方式最简单,只需存储和取用,线程同步的操作交由LinkedBlockingQueue全权处理。
相关文章推荐
- SAP MRP的计算步骤
- 常见排序算法基于JS的实现
- HTML焦点与键盘事件
- 计蒜客 难题题库 142 求数组的最长递减子序列
- CodeForces 527C Glass Carving(multiset)
- ISP、IAP、ICP烧写方式的区别
- Linux 数据库学习的准备工作---mysql数据库的安装
- IOS在自己网站发布APP(企业版$299上线流程)
- 0.python基本算法
- js获取时间的函数
- 电脑维修知识——开机无显示
- 绑定手机号,并发送段信验证码
- Spring Mobile是如何判断访问设备的类型的
- Tomcat总体架构(Tomcat源码解析系列二)
- PowerCmd 2.2 注册码
- More is better---hdu1856(并查集)
- 3.4-3.5-rsync后台服务方式
- 计蒜客 难题题库 141 非递归二叉树的前序遍历
- 数据库事务并发带来的问题、及并行
- csdn分类功能有问题