notify()
,用signalAll()
替换notifyAll()
,传统线程的通信方式,Condition
都可以实现,这里注意,Condition
是被绑定到Lock
上的,要创建一个Lock
的Condition
必须用newCondition()
方法。
public class ThreadTest2 {
public static void main(String[] args) {
final Business business = new Business();
new Thread(new Runnable() {
@Override
public void run() {
threadExecute(business, "sub");
}
}).start();
threadExecute(business, "main");
}
public static void threadExecute(Business business, String threadType) {
for(int i = 0; i < 100; i++) {
try {
if("main".equals(threadType)) {
business.main(i);
} else {
business.sub(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Business {
private boolean bool = true;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public /*synchronized*/ void main(int loop) throws InterruptedException {
lock.lock();
try {
while(bool) {
condition.await();//this.wait();
}
for(int i = 0; i < 100; i++) {
System.out.println("main thread seq of " + i + ", loop of " + loop);
}
bool = true;
condition.signal();//this.notify();
} finally {
lock.unlock();
}
}
public /*synchronized*/ void sub(int loop) throws InterruptedException {
lock.lock();
try {
while(!bool) {
condition.await();//this.wait();
}
for(int i = 0; i < 10; i++) {
System.out.println("sub thread seq of " + i + ", loop of " + loop);
}
bool = false;
condition.signal();//this.notify();
} finally {
lock.unlock();
}
}
}
这样看来,Condition
和传统的线程通信没什么区别,Condition
的强大之处在于它可以为多个线程间建立不同的Condition
.
package com.concurrent.forkjoinpool;
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(); //读线程条件
Object[] items = new Object[100]; //缓存队列
int putptr/*写索引*/, takeptr/*读索引*/, count/*缓存中元素个数*/;
public void put(Object x) throws InterruptedException{
try{
lock.lock();
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{
try{
lock.lock();
while(count == 0)
notEmpty.await();
Object x = items[takeptr];
if(++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
}finally{
lock.unlock();
}
}
}
这就是多个Condition
的强大之处,如果缓存队列已满,阻塞的肯定是写线程,唤醒的肯定是读线程;若只有单个Condition
,不知道唤醒的是读线程还是写线程,若是读线程,皆大欢喜,若是写线程,刚被唤醒立即被阻塞.