Condition的特性:
1.Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signalAll()相当于Object的notifyAll()方法。不同的是,Object中的这些方法是和同步锁捆绑使用的,而Condition是需要与互斥锁/共享锁捆绑使用的。
2.Condition它更强大的地方在于:能够更加精细的控制多线程的休眠与唤醒。对于同一个锁,我们可以创建多个Condition,在不同的情况下使用不同的Condition。如果采用Object类中的wait(), notify(), notifyAll(),不可能通过notify()或notifyAll()明确的指定唤醒"线程",而只能通过notifyAll唤醒所有线程(但是notifyAll无法区分唤醒的线程是读线程,还是写线程)。 但是,通过Condition,就能明确的指定唤醒线程。
公共资源:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 公共资源,包含消费和生产两个方法
*/
public class Basket {
private Lock lock;
private Condition produced;
private Condition consumed;
private int num;
public Basket(){
lock = new ReentrantLock();
produced = lock.newCondition();
consumed = lock.newCondition();
}
public void produce() throws InterruptedException {
lock.lock();
System.out.println("Producer get a lock...");
try {
while(num==1){
System.out.println("Producer sleep...");
produced.await();
}
Thread.sleep(1000);
System.out.println("Producer produce an apple");
num = 1;
consumed.signal();
} finally {
lock.unlock();
}
}
public void consume() throws InterruptedException {
lock.lock();
System.out.println("Consumer get a lock...");
try {
while(num == 0){
System.out.println("Consumer sleep...");
consumed.await();
}
Thread.sleep(500);
System.out.println("Consumer consume an apple");
num = 0;
produced.signal();
} finally {
lock.unlock();
}
}
}
生产者:
public class Producer implements Runnable {
private Basket basket;
public Producer(Basket basket){
this.basket = basket;
}
@Override
public void run() {
try {
basket.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
消费者:
public class Consumer implements Runnable {
private Basket basket;
public Consumer(Basket basket){
this.basket = basket;
}
@Override
public void run() {
try {
basket.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
测试代码:
public class BaskerTest {
private static int corePoolSize = 4;
private static int maximumPoolSize = 20;
private static long keepAlive = 100;
public static void main(String[] args) {
Basket basket = new Basket();
ExecutorService service = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAlive, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(20));
//ExecutorService service = Executors.newCachedThreadPool();
for(int i=0;i<3;i++){
service.submit(new Producer(basket));
}
for(int i=0; i<3; i++){
service.submit(new Consumer(basket));
}
service.shutdown();
}
}