main方法
package com.chinaso.test;
//http://www.importnew.com/15731.html
public class Main {
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);
}
}
ApplicationStartupUtil
package com.chinaso.test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import com.chinaso.test.checker.BaseHealthChecker;
import com.chinaso.test.checker.CacheHealthChecker;
import com.chinaso.test.checker.DatabaseHealthChecker;
import com.chinaso.test.checker.NetworkHealthChecker;
public class ApplicationStartupUtil{
//List of service checkers
private static List<BaseHealthChecker> _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<BaseHealthChecker>();
_services.add(new NetworkHealthChecker(_latch)); //把三个线程加入list
_services.add(new CacheHealthChecker(_latch));
_services.add(new DatabaseHealthChecker(_latch));
//Start service checkers using executor framework
Executor executor = Executors.newFixedThreadPool(_services.size()); //创建一个固定长度的线程池
for(final BaseHealthChecker v : _services)
{
executor.execute(v); //启动三个检测线程
}
//Now wait till all services are checked
_latch.await(); //计数器等待... ?
System.out.println("主线程被唤醒,检测服务是否正常...");
//Services are file and now proceed startup
for(final BaseHealthChecker v : _services)
{
if( ! v.isServiceUp())
{
return false; //遍历
}
}
return true;
}
}
BaseHealthChecker
package com.chinaso.test.checker;
import java.util.concurrent.CountDownLatch;
public abstract class BaseHealthChecker implements Runnable {
private CountDownLatch _latch;
private String _serviceName;
private boolean _serviceUp;
//Get latch object in constructor so that after completing the task, thread can countDown() the latch
public BaseHealthChecker(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) {
t.printStackTrace(System.err);
_serviceUp = false;
} finally {
if(_latch != null) {
_latch.countDown(); //run方法执行完,计数器减 1
}
}
}
public String getServiceName() {
return _serviceName;
}
public boolean isServiceUp() {
return _serviceUp;
}
//This methos needs to be implemented by all specific service checker
public abstract void verifyService();
}
CacheHealthChecker
package com.chinaso.test.checker;
import java.util.concurrent.CountDownLatch;
/**
*
* @author ZZN
* 父类是一个线程类,在父类中定义了一个抽象方法,在父类的run()方法中调用这个抽象方法,来实现对服务的检测
*/
public class CacheHealthChecker extends BaseHealthChecker{
public CacheHealthChecker (CountDownLatch latch) {
super("Cache Service", latch);
}
@Override
public void verifyService(){
System.out.println("Checking " + this.getServiceName()+"...");
try{
Thread.sleep(5000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(this.getServiceName() + " is UP");
}
}
DatabaseHealthChecker
package com.chinaso.test.checker;
import java.util.concurrent.CountDownLatch;
public class DatabaseHealthChecker extends BaseHealthChecker{
public DatabaseHealthChecker (CountDownLatch latch) {
super("Database Service", latch);
}
@Override
public void verifyService(){
System.out.println("Checking " + this.getServiceName()+"...");
try{
Thread.sleep(6000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(this.getServiceName() + " is UP");
}
}
NetworkHealthChecker
package com.chinaso.test.checker;
import java.util.concurrent.CountDownLatch;
public class NetworkHealthChecker extends BaseHealthChecker{
public NetworkHealthChecker (CountDownLatch latch) {
super("Network Service", latch);
}
@Override
public void verifyService(){
System.out.println("Checking " + this.getServiceName()+"...");
try{
Thread.sleep(7000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(this.getServiceName() + " is UP");
}
}