Condition的功能类似在传统线程技术中的Object.wait和Object.notity的功能。一个锁内部可以有多个Condition,即有多路等待和通知,可以参看Jdk1.5提供的Lock和Condition实现的可阻塞队列的应用案例。在传统的线程机制中一个监视器对象上只能有一路等待和通知,要想实现多路等待和通知,必须嵌套使用多个同步监视器对象。
例一:
JDK文档中提供了一个很不错的示例(http://docs.oracle.com/javase/6/docs/api/ ),用Condition实现一个阻塞队列,代码如下:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length)
putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length)
takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
例二:
三个线程 循环打印 : 线程1唤醒线程2,线程2唤醒线程3,线程3唤醒线程1。
package com.huang.test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* java 条件阻塞——condition
* 三个线程 循环打印 : 线程1唤醒线程2,线程2唤醒线程3,线程3唤醒线程1
* @author wuseyukui
*
*/
public class ThreadTest {
private boolean isMainRun = true;
private boolean isSub1Run = false;
private boolean isSub2Run = false;
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
public static void main(String[] args) {
new ThreadTest().init();
}
private void init() {
new ThreadMain().start();
new ThreadSon1().start();
new ThreadSon2().start();
}
class ThreadMain extends Thread {
@Override
public void run() {
for (int i = 1; i < 6; i++) {
main(i);
}
}
}
class ThreadSon1 extends Thread {
@Override
public void run() {
for (int i = 1; i < 6; i++) {
sub1(i);
}
}
}
class ThreadSon2 extends Thread {
@Override
public void run() {
for (int i = 1; i < 6; i++) {
sub2(i);
}
}
}
private /*synchronized*/ void main(int i) {
lock.lock();
while (!isMainRun) {
try {
// wait();
condition1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 0; j < 10; j++) {
System.out.println(" 主线程打印:" + (j + 1) + ",第" + i + "个循环");
}
isSub1Run = true;
isMainRun = false;
condition2.signal();
// notify();
lock.unlock();
}
private /*synchronized*/ void sub1(int i) {
lock.lock();
while (!isSub1Run) {
try {
// wait();
condition2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 0; j < 20; j++) {
System.out.println(" 子线程1打印:" + (j + 1) + ",第" + i + "个循环");
}
isSub2Run = true;
isSub1Run = false;
condition3.signal();
// notify();
lock.unlock();
}
private /*synchronized*/ void sub2(int i) {
lock.lock();
while (!isSub2Run) {
try {
// wait();
condition3.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 0; j < 20; j++) {
System.out.println(" 子线程2打印:" + (j + 1) + ",第" + i + "个循环");
}
isMainRun = true;
isSub2Run = false;
condition1.signal();
// notify();
lock.unlock();
}
}