接上一回,如果4个工人在装配车轮时,工作间中没有车轮可装配,工人必须等到车轮运送到工作间合适的位置后才可以进行装配车轮的工作。所以,在Worker类中加入一把新的CountDownLatch-----tyreReadyLatch,
让这把锁告诉Worker线程,在轮胎到来之前,必须处于等待状态,假如不等待的话,这个Worker线程会跑出错误,导致的结果是这辆车装配轮胎整个任务失败。所以必须调用
tyreReadyLatch.await();
这个语句确保Worker线程在等待轮胎的到来。
BlockingQueue来模拟当前工作间中放轮胎的位置。假设能放下4个轮胎。往这个Queue中放入4个轮胎,运送轮胎的工作在main函数中完成
for (int i = 0; i < 4; i++){
tyries.offer(new Tyre(i));
Thread.sleep(500);
}
OK,4个轮胎就位后,调用下面这个语句,释放tyreReadyLatch,初始化时,tyreReadyLatch锁的计数器被设置为1,所以只需要调用一次tyreReadyCount的countDown()方法。以告诉4个Worker线程,你们可以进行轮胎的装配工作。
tyreReadyLatch.countDown();
下面的这行代码模拟Worker线程在接受到可以进行装配工作的“指令”后,从工作间里拿出一个轮胎。
Tyre tyre = tyries.take();
拿到轮胎后,Worker线程的工作模式和第一回中的工人装配轮胎一节中的行为是一样的了。
可见,使用多个CountDownLatch可以比较精确的控制一个线程的运行状态。CountDownLatch的await和countDown方法必须配合使用。否则会造成线程一直处于等待状态。
最后,完整的代码清单。
public class Worker implements Runnable {
private String name;
static CountDownLatch workDoneLatch = new CountDownLatch(4);
static CountDownLatch tyreReadyLatch = new CountDownLatch(1);
static ArrayBlockingQueue<Tyre> tyries = new ArrayBlockingQueue<Tyre>(4);
public Worker(String name) {
this.name = name;
}
@Override
public void run() {
try {
System.out.format("%s is waiting for tyre ready....%n", name);
tyreReadyLatch.await();
Tyre tyre = tyries.take();
System.out.format("%s is assembling.%n", tyre);
marshalTyre();
System.out.format("%s is assembled.%n", tyre);
workDoneLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void marshalTyre() throws InterruptedException {
Thread.sleep(new Random().nextInt(60000));
}
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
long s = System.currentTimeMillis();
String works[] = { "John Chembers", "Bill Gates", "Larry Page", "Ericsson Limited" };
for (int i = 0; i < 4; i++)
executorService.execute(new Worker(works[i]));
for (int i = 0; i < 4; i++){
tyries.offer(new Tyre(i));
Thread.sleep(500);
}
tyreReadyLatch.countDown();
workDoneLatch.await();
System.out.format("the 4 tyres were assembled. costs %d ms.%n", System.currentTimeMillis() - s);
executorService.shutdown();
}
}
辅助类Tyre,代表轮胎
class Tyre {
private int id;
public Tyre(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Tyre: " + id;
}
}
[原创内容,版权所有,如有转载,请注明出处,如有错误之处,请指出,不胜感激]