CountDownLatchを使用して複数のスレッドの実行順序を制御

2669 ワード

複数のスレッドが同時に動作し、そのうちのいくつかは任意に同時に実行できるようにする必要がある場合がありますが、1つのスレッドは他のスレッドの動作が終了してから開始する必要があります.たとえば、複数のスレッドブロックを開いて大きなファイルをダウンロードし、各スレッドは固定されたセグメントのみをダウンロードし、最後に別のスレッドですべてのセグメントをつなぎ合わせると、CountDownLatchを使用して同時制御を行うことが考えられます.
    CountDownLatchはJAVAがjava.util.concurrentパッケージの下に提供する補助クラスであり、それをカウンタと見なすことができ、その内部にはcountカウントが維持されているが、このカウンタの操作はすべて原子操作であると同時に、このカウンタを操作するスレッドは1つしかなく、CountDownLatchは構造関数を通じて初期カウント値を入力し、呼び出し元は、CounDownLatchオブジェクトのcutDown()メソッドを呼び出すことによって、カウントを1減少させることができる.オブジェクト上のawait()メソッドを呼び出すと、呼び出し元はcutDownメソッドを介してカウントを0に減らすまでここでブロックされます.
import java.util.concurrent.CountDownLatch;
 
 public class Sample {
    /**
     *    ,      
      *     2,        2
      */
     private final static CountDownLatch mCountDownLatch = new CountDownLatch(2);
     /**
      *        
      */
     private static class WorkingThread extends Thread {
         private final String mThreadName;
         private final int mSleepTime;
         public WorkingThread(String name, int sleepTime) {
             mThreadName = name;
             mSleepTime = sleepTime;
         }
         
         @Override
         public void run() {
             System.out.println("[" + mThreadName + "] started!");
             try {  
                     Thread.sleep(mSleepTime);  
             } catch (InterruptedException e) {  
                     e.printStackTrace();  
             }
             mCountDownLatch.countDown();
             System.out.println("[" + mThreadName + "] end!"); 
        }
    }
     
     /**
      *      
      */
    private static class SampleThread extends Thread {
         
        @Override
        public void run() {
            System.out.println("[SampleThread] started!");
            try {
                //          mCountDownLatch   count  0;
                //         WorkingThread  countDown()
                mCountDownLatch.await();
            } catch (InterruptedException e) {
                
            }
             System.out.println("[SampleThread] end!");
        }
    }
    
    public static void main(String[] args) throws Exception {
        //   run SampleThread
        new SampleThread().start();
        //         
       //     1  5 
        new WorkingThread("WorkingThread1", 5000).start();
        //     2  2 
        new WorkingThread("WorkingThread2", 2000).start();
     }
}

実行結果:
[SampleThread] started![WorkingThread1] started![WorkingThread2] started![WorkingThread2] end![WorkingThread1] end![SampleThread] end!
目的を達成した.もちろん、このような効果が得られる方法は他にもありますが、本稿ではCountDownLatchを使用する方法を紹介しただけです.