一、Condition介绍
Condition将Object监视器方法(wait、notify和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意Lock实现组合使用。
其中Lock与synchronized区别:
①、Lock替代了synchronized方法的使用及作用,
②、Condition替代了Object监视器方法的使用及作用。
③、Condition的await方法代替Object的wait;
④、Condition的signal方法代替Object的notify方法;
⑤、Condition的signalAll方法代替Object的notifyAll方法。
⑥Condition实例在使用时需要绑定到一个锁上,可以通过newCondition方法获取Condition实例。
二、Condition中的两种重要的方法
①、 await():造成当前线程在接到信号或被中断之前一直处于等待状态。
②、signal():唤醒一个等待线程( signalAll() :唤醒所有等待线程。)。
(这两个只是我这个例子使用的方法,如果想要了解Condition的更多的方法,可以去http://tool.oschina.net/apidocs/apidoc?api=jdk-zh查看Condition的API)
1.Java代码利用Condition实现一个生产者消费者模式示例
package chapter3.condition;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author czd
*/
public class ConditionTest1 {
private static ReentrantLock reentrantLock = new ReentrantLock();
private static Condition condition = reentrantLock.newCondition();
private static Integer data = 0;
private static volatile boolean noUse = true;
public static void main(String[] args) {
new Thread(){
@Override
public void run() {
while (true){
produceData();
}
}
}.start();
new Thread(){
@Override
public void run() {
while (true){
consumerData();
}
}
}.start();
}
/**
* 生产者生成数据
*/
public static void produceData() {
try {
reentrantLock.lock();
while (noUse){
condition.await();
}
data++;
System.out.println("生产一个数据:" + data);
TimeUnit.SECONDS.sleep(2);
noUse = true;
condition.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
reentrantLock.unlock();
}
}
/**
* 消费者消费数据
*/
public static void consumerData() {
try {
reentrantLock.lock();
while (!noUse){
condition.await();
}
System.out.println("消费者消费一个数据:" + data);
TimeUnit.SECONDS.sleep(2);
noUse = false;
condition.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
reentrantLock.unlock();
}
}
}
输出结果
2.Java代码利用Condition实现一个多线程下生产者消费者(进阶版)
package chapter3.condition;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author czd
*/
public class ConditionTest2 {
private static ReentrantLock reentrantLock = new ReentrantLock();
private static Condition produceCondition = reentrantLock.newCondition();
private static Condition consumerCondition = reentrantLock.newCondition();
private static LinkedList<Long> dataPool = new LinkedList<>();
private final static Integer MAX = 100;
public static void main(String[] args) {
for (int i = 0; i < 5; i++){
new Thread("Producer--" + i){
@Override
public void run() {
produceData();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
for (int i = 0; i < 10; i++){
new Thread("Consumer--" + i){
@Override
public void run() {
consumerData();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}
/**
* 生产者生成数据
*/
public static void produceData() {
try {
reentrantLock.lock();
while (dataPool.size() >= MAX){
produceCondition.await();
}
Long value = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + " 生产了一个数据>>>" + value);
dataPool.addLast(value);
consumerCondition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
reentrantLock.unlock();
}
}
/**
* 消费者消费数据
*/
public static void consumerData() {
try {
reentrantLock.lock();
while (dataPool.isEmpty()){
consumerCondition.await();
}
Long value = dataPool.removeFirst();
System.out.println(Thread.currentThread().getName() + " 消费了一个数据>>>" + value);
produceCondition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
reentrantLock.unlock();
}
}
}
输出结果