CountDownLatch
被用来同步一个或多个任务,强制它们等待由其他任务执行的一组操作完成。
CountDownLatch的方法:
1.构造方法中有初始值表示需要等待的事件的数量
2.await()方法,被等待全部时间中介的线程调用
3.countDown()方法,事件在结束执行后调用
当创建 CountDownLatch 对象时,对象使用构造函数的参数来初始化内部计数器。
每次调用 countDown() 方法, CountDownLatch 对象内部计数器减一。
当内部计数器达到0时, CountDownLatch 对象唤醒全部使用 await() 方法睡眠的线程们。
不可能重新初始化或者修改CountDownLatch对象的内部计数器的值。
一旦计数器的值初始后,唯一可以修改它的方法就是之前用的 countDown() 方法。
当计数器到达0时, 全部调用 await() 方法会立刻返回,接下来任何countDown() 方法的调用都将不会造成任何影响。
适用:
例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。
import java.util.concurrent.CountDownLatch;
public abstract class Base implements Runnable {
private CountDownLatch _latch;
private String _serviceName;
private boolean _serviceUp;
public Base(String serviceName, CountDownLatch latch) {
super();
this._latch = latch;
this._serviceName = serviceName;
this._serviceUp = false;
}
@Override
public void run() {
try {
verifyService();
_serviceUp = true;
} catch (Throwable t) {
System.out.println(t);
_serviceUp = false;
} finally {
if (_latch != null) {
_latch.countDown();
}
}
}
public boolean isServiceUp() {
return _serviceUp;
}
public String getServiceName() {
return _serviceName;
}
public abstract void verifyService();
}
import java.util.concurrent.CountDownLatch;
public class NetWork extends Base {
public NetWork(CountDownLatch latch) {
super("NetWork Service", latch);
}
@Override
public void verifyService() {
System.out.println("Checking " + this.getServiceName());
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println(this.getServiceName() + " is UP");
}
}
import java.util.concurrent.CountDownLatch;
public class Database extends Base {
public Database(CountDownLatch latch) {
super("Database Service", latch);
}
@Override
public void verifyService() {
System.out.println("Checking " + this.getServiceName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println(this.getServiceName() + " is UP");
}
}
import java.util.concurrent.CountDownLatch;
public class Cache extends Base {
public Cache(CountDownLatch latch) {
super("Cache Service", latch);
}
@Override
public void verifyService() {
System.out.println("Checking " + this.getServiceName());
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println(this.getServiceName() + " is UP");
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ApplicationStart {
private static List<Base> _service;
private static CountDownLatch _latch;
private ApplicationStart() {
}
private static class LazyLoad {
private static final ApplicationStart INSTANCE = new ApplicationStart();
}
public static ApplicationStart getInstance() {
return LazyLoad.INSTANCE;
}
public static boolean check() throws Exception {
_latch = new CountDownLatch(3);
_service = new ArrayList<Base>();
_service.add(new NetWork(_latch));
_service.add(new Database(_latch));
_service.add(new Cache(_latch));
ExecutorService executor = Executors
.newFixedThreadPool(_service.size());
for (final Base b : _service) {
executor.execute(b);
}
executor.shutdown();
_latch.await();
for (final Base b : _service) {
if (!b.isServiceUp()) {
return false;
}
}
return true;
}
public static void main(String[] args) {
ApplicationStart as = new ApplicationStart();
boolean result = false;
try {
result = as.check();
} catch (Exception e) {
System.out.println(e);
}
System.out.println("result : " + result);
}
}
output:
Checking NetWork Service
Checking Database Service
Checking Cache Service
Database Service is UP
Cache Service is UP
NetWork Service is UP
result : true