JAVAプレミアム(7)-同時CountDownLatch

5558 ワード

一、何ですか


CountDownLatchはjavaです.util.concurrentパッケージの下にある同期ツールクラスでは、他のスレッドの操作が完了するまで1つ以上のスレッドを待機させ、ロックで待機しているスレッドが実行タスクを再開できます.たとえば、アプリケーションのプライマリ・スレッドは、フレームワーク・サービスの開始を担当するスレッドがすべてのフレームワーク・サービスを開始した後に実行することを望んでいます.CountDownLatchの疑似コードは以下の通りです.
//Main thread start
//Create CountDownLatch for N threads
//Create and start N threads
//Main thread wait on latch
//N threads completes there tasks are returns
//Main thread resume execution

二、どのように仕事をするか


コンストラクション関数:public void CountDownLatch(int count)コンストラクタのカウント値(count)は、実際にはロックに待機するスレッドの数です.この値は一度しか設定できず、このカウント値を再設定するメカニズムはありません.プライマリ・スレッドは、他のスレッドが開始された直後にawait()メソッドを呼び出す必要があります.これにより、プライマリ・スレッドの操作は、他のスレッドがそれぞれのタスクを完了するまで、この方法でブロックされます.他のNスレッドは、CountDownLatchオブジェクトに通知する必要があるため、それぞれのタスクを完了したロックオブジェクトを参照する必要があります.countDown()法によって達成された.このメソッドを呼び出すたびに,コンストラクション関数で初期化されたcount値は1減少する.したがって,N個のスレッドがこのメソッドを呼び出すとcountの値は0に等しくなり,メインスレッドはawait()メソッドを介して自分のタスクの実行を再開することができる.

三、例


この例では、アプリケーション起動クラスをシミュレートし、開始時にn個のスレッドクラスを起動しました.これらのスレッドは外部システムをチェックし、閉鎖を通知し、起動クラスは閉鎖上待機しています.すべての外部サービスが検証され、チェックされると、クラスリカバリ実行が開始されます.
BaseHealthChecker.JAva:このクラスはRunnableで、すべての特定の外部サービス健康の検査を担当しています.
public abstract class BaseHealthChecker implements Runnable {
    private CountDownLatch latch;
    private String serviceName;
    private boolean isReady;

    // Get latch object in constructor so that after completing the task, thread
    // can countDown() the latch
    public BaseHealthChecker(String serviceName, CountDownLatch latch) {
        this.latch = latch;
        this.serviceName = serviceName;
        this.isReady = false;
    }

    public void run() {
        try {
            verifyService();
            isReady = true;
        } catch (Throwable t) {
            t.printStackTrace(System.err);
            isReady = false;
        } finally {
            if (latch != null) {
                latch.countDown();
            }
        }
    }

    public String getServiceName() {
        return serviceName;
    }

    public boolean isReady() {
        return isReady;
    }

    // This method needs to be implemented by all specific service checker
    public abstract void verifyService();
}
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 READY");
    }
}
    public CacheHealthChecker(CountDownLatch latch) {
        super("Cache 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 READY");
    }

ApplicationStartupUtil:このクラスは、すべてのサービスが検出されるまで、ロックを初期化し、待機するプライマリ起動クラスです.
public class ApplicationStartupUtil {
    // List of service checkers
    private static List 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);

        // All add checker in lists
        services = new ArrayList();
        services.add(new NetworkHealthChecker(latch));
        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();

        // Services are file and now proceed startup
        for (final BaseHealthChecker v : services) {
            if (!v.isReady()) {
                return false;
            }
        }
        return true;
    }
}
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);
    }
}

出力:Checking Network Service Checking Cache Service is READY Network Service is READY External services validation completed!Result was::true

よくある面接問題

  • CountDownLatchの概念を説明しますか?
  • CountDownLatchの使用例をいくつか示しますか?
  • CountDownLatchクラスの主な方法は?

  • 参考文献


    いつCountDownLatchを使うか