ApplicationStartupUtil
package com.chinaso.mytest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.chinaso.mytest.CacheHealthChecker;
import com.chinaso.mytest.DatabaseHealthChecker;
import com.chinaso.mytest.NetworkHealthChecker;
public class ApplicationStartupUtil{
//List of service checkers
private static List<Callable<Boolean>> _services;
//This latch will be used to wait on
private static CountDownLatch _latch;
private ApplicationStartupUtil(){
}
private final static ApplicationStartupUtil INSTANCE = new ApplicationStartupUtil();
public static ApplicationStartupUtil getInstance(){
return INSTANCE;
}
public static boolean checkExternalServices() throws Exception{
//Initialize the latch with number of service checkers
_latch = new CountDownLatch(3); //计数器初始化为 3
//All add checker in lists
_services = new ArrayList<Callable<Boolean>>();
_services.add(new NetworkHealthChecker(_latch)); //把三个线程加入list,还能遍历list来获得线程的成员变量值?
_services.add(new CacheHealthChecker(_latch));
_services.add(new DatabaseHealthChecker(_latch));
//Start service checkers using executor framework
ExecutorService executor = Executors.newFixedThreadPool(_services.size()); //创建一个固定长度的线程池
List<Future<Boolean>> resultList = new ArrayList<Future<Boolean>>();
for(final Callable<Boolean> v : _services)
{
System.out.println("调用线程..."+v.hashCode());
Future<Boolean> future = executor.submit(v); //启动三个检测线程,程序不会在这条指令上卡住,而是会顺序执行,至于什么时候线程把结果回写给future,是线程自己的事
//System.out.println("调用线程..."+v.hashCode()+future.get());
//将任务执行结果存储到List中
resultList.add(future);
System.out.println("调用线程..."+v.hashCode()+"result.size():->["+resultList.size()+"]"); //这一步list里是有值的,也就是future对象,但future里面的值要等到线程执行完毕后才能回写到future里
}
//Now wait till all services are checked
_latch.await(); //计数器等待...
System.out.println("主线程被唤醒,检测服务是否正常...");
//Services are file and now proceed startup
for(final Future<Boolean> v : resultList)
{
if( ! v.get())
{
return false; //遍历
}
}
return true;
}
public static void main(String[] args){
boolean result = false;
try {
result = ApplicationStartupUtil.checkExternalServices();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("External services validation completed !! Result was :: "+ result);
}
}
CacheHealthChecker
package com.chinaso.mytest;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
/**
*
* @author ZZN
* 父类是一个线程类,在父类中定义了一个抽象方法,在父类的run()方法中调用这个抽象方法,来实现对服务的检测
*/
public class CacheHealthChecker implements Callable<Boolean>{
private CountDownLatch _latch;
private String _serviceName;
private boolean _serviceUp;
public CacheHealthChecker (CountDownLatch latch) {
this._latch = latch;
this._serviceName = "Cache Service";
this._serviceUp = false;
}
//Get latch object in constructor so that after completing the task, thread can countDown() the latch
public CacheHealthChecker(String serviceName, CountDownLatch latch)
{
this._latch = latch;
this._serviceName = serviceName;
this._serviceUp = false;
}
@Override
public Boolean call() {
try {
//---------------------------------------------------------------
System.out.println("Checking " + this._serviceName+"...");
try{
Thread.sleep(5000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(this._serviceName + " is UP");
//---------------------------------------------------------------
_serviceUp = true;
} catch (Throwable t) {
t.printStackTrace(System.err);
_serviceUp = false;
} finally {
if(_latch != null) {
_latch.countDown(); //run方法执行完,计数器减 1
}
}
return _serviceUp;
}
}
DatabaseHealthChecker
package com.chinaso.mytest;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
/**
*
* @author ZZN
* 父类是一个线程类,在父类中定义了一个抽象方法,在父类的run()方法中调用这个抽象方法,来实现对服务的检测
*/
public class DatabaseHealthChecker implements Callable<Boolean>{
private CountDownLatch _latch;
private String _serviceName;
private boolean _serviceUp;
public DatabaseHealthChecker (CountDownLatch latch) {
this._latch = latch;
this._serviceName = "Database Service";
this._serviceUp = false;
}
//Get latch object in constructor so that after completing the task, thread can countDown() the latch
public DatabaseHealthChecker(String serviceName, CountDownLatch latch)
{
this._latch = latch;
this._serviceName = serviceName;
this._serviceUp = false;
}
@Override
public Boolean call() {
try {
//---------------------------------------------------------------
System.out.println("Checking " + this._serviceName+"...");
try{
Thread.sleep(6000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(this._serviceName + " is UP");
//---------------------------------------------------------------
_serviceUp = true;
} catch (Throwable t) {
t.printStackTrace(System.err);
_serviceUp = false;
} finally {
if(_latch != null) {
_latch.countDown(); //run方法执行完,计数器减 1
}
}
return _serviceUp;
}
}
NetworkHealthChecker
package com.chinaso.mytest;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
/**
*
* @author ZZN
* 父类是一个线程类,在父类中定义了一个抽象方法,在父类的run()方法中调用这个抽象方法,来实现对服务的检测
*/
public class NetworkHealthChecker implements Callable<Boolean>{
private CountDownLatch _latch;
private String _serviceName;
private boolean _serviceUp;
public NetworkHealthChecker (CountDownLatch latch) {
this._latch = latch;
this._serviceName = "Network Service";
this._serviceUp = false;
}
//Get latch object in constructor so that after completing the task, thread can countDown() the latch
public NetworkHealthChecker(String serviceName, CountDownLatch latch)
{
this._latch = latch;
this._serviceName = serviceName;
this._serviceUp = false;
}
@Override
public Boolean call() {
try {
//---------------------------------------------------------------
System.out.println("Checking " + this._serviceName+"...");
try{
Thread.sleep(7000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(this._serviceName + " is UP");
//---------------------------------------------------------------
_serviceUp = true;
} catch (Throwable t) {
t.printStackTrace(System.err);
_serviceUp = false;
} finally {
if(_latch != null) {
_latch.countDown(); //run方法执行完,计数器减 1
}
}
return _serviceUp;
}
}