/**
*
*/
package com.me.threadtest;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* 多线程之生产者与消费者模式升级版
*
* 1、jdk1.5新特性:用Lock代替synchronized,
* Condition代替wait() notify() notifyAll(),
*
* 2、 condition对象通过lock锁获取,
* 一个Lock锁可以对应多个condition对象,
* 而在jdk1.5之前的同步中,只能有一个锁,
* 一旦有多个锁,就代表着有多个同步代码,容易造成同步嵌套,
* 进而产生死锁问题!
* condition实例只唤醒对方的线程。
*
*/
public class ProducerAndConsumerPlus {
public static void main(String[] args) {
CommodityTest commodity = new CommodityTest();
//创建生产线程对象
ProviderTest pro = new ProviderTest(commodity);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
//创建消费线程对象
CustomerTest cus = new CustomerTest(commodity);
Thread t3 = new Thread(cus);
Thread t4 = new Thread(cus);
//启动线程
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class CommodityTest {
private String name;
private int count = 1;
private boolean flag = false;
//创建锁对象
private Lock lock = new ReentrantLock();
//获取Condition,一个lock可以对应多个condition对象,
//每个condition对象可以代表不同线程
// Condition condition = lock.newCondition();
//生产者线程所属 的condition
Condition conditionProv = lock.newCondition();
//消费者线程所属的condition
Condition conditionCust = lock.newCondition();
//生产商品
public void set(String name) throws InterruptedException {
lock.lock(); //加锁
try {
while (flag) {
conditionProv.await(); //等待
}
this.name = name + "---" + count++;
System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
flag = true;
// condition.signalAll(); //唤醒所有等待线程,包括本方
conditionCust.signal(); //唤醒对方消费者线程
} finally {
lock.unlock(); //释放锁
}
}
//消费商品
public void out() throws InterruptedException {
lock.lock(); //加锁
try {
while (!flag) {
conditionCust.await(); //线程等待
}
System.out.println(Thread.currentThread().getName() + "........消费者....." + this.name);
flag = false;
conditionProv.signal(); //唤醒生产者线程
} finally {
lock.unlock(); //释放锁
}
}
}
class ProviderTest implements Runnable {
private CommodityTest commodity;
public ProviderTest(CommodityTest commodity) {
this.commodity = commodity;
}
@Override
public void run() {
while (true) {
try {
commodity.set("麻辣烫");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class CustomerTest implements Runnable {
private CommodityTest commodity;
public CustomerTest(CommodityTest commodity) {
this.commodity = commodity;
}
@Override
public void run() {
while (true) {
try {
commodity.out();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}