Java Semaphore、CyclicBarrier、CountDownLatch

4615 ワード

問:メソッドが同時アクセスされる個数をどのように制御しますか?
答え:Semaphoreを使用できます.次の2つのコアメソッドがあります.
  • semaphore.acquire():は、信号量の個数を1減少させる信号量を要求するために使用される.使用可能な信号量がない場合、すなわち信号量個数が負になると、メソッド要求が再び呼び出されると、他のスレッドが信号量を解放するまでブロックされる.
  • semaphore.release():は、信号量の個数に1を加算する信号量を解放するために使用される.

  • したがって、本題の最も簡単な実装スキームコードは以下の通りである(同時に最大5つの同時アクセスが可能である):
    public class SemaphoreTest {  
        private Semaphore mSemaphore = new Semaphore(5);  
    
        public void testRun() {  
            for(int i=0; i< 20; i++){  
                new Thread(new Runnable() {  
                    @Override  
                    public void run() {  
                        test();  
                    }  
                }).start();  
            }  
        }  
    
        private void test(){  
            try {  
                mSemaphore.acquire();  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
            System.out.println(Thread.currentThread().getName() + " enter...");  
            try {  
                Thread.sleep(100);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
            System.out.println(Thread.currentThread().getName() + " exit...");  
            mSemaphore.release();  
        }  
    } 
    

    出力は次のとおりです.
    Thread-1 enter...
    Thread-2 enter...
    Thread-3 enter...
    Thread-4 enter...
    Thread-5 enter...
    Thread-1 exit...
    Thread-6 enter...
    Thread-2 exit...
    Thread-7 enter...
    Thread-3 exit...
    Thread-8 enter...
    Thread-4 exit...
    Thread-9 enter...
    Thread-5 exit...
    Thread-10 enter...
    Thread-7 exit...
    Thread-6 exit...
    Thread-11 enter...
    Thread-12 enter...
    Thread-8 exit...
    Thread-13 enter...
    Thread-10 exit...
    Thread-14 enter...
    Thread-9 exit...
    Thread-15 enter...
    Thread-11 exit...
    Thread-12 exit...
    Thread-16 enter...
    Thread-17 enter...
    Thread-15 exit...
    Thread-18 enter...
    Thread-14 exit...
    Thread-19 enter...
    Thread-13 exit...
    Thread-20 enter...
    Thread-16 exit...
    Thread-19 exit...
    Thread-17 exit...
    Thread-18 exit...
    Thread-20 exit...
    

    質問:JavaでCyclicBarrierとCountDownLatchは何が違いますか?
    答え:CountDownLatchとCyclicBarrierはいずれもスレッド間の待機を実現できるが,それらの側面の重点は異なる.
  • CountDownLatchは、通常、あるスレッドAが複数の他のスレッドがタスクを実行した後に実行されるのを待つために使用されます.
  • CyclicBarrierは、一般に、スレッドのセットがある状態まで待機し、その後、スレッドのセットが同時に実行されるように使用される.
  • さらに、CountDownLatchは再利用できないが、CyclicBarrierは再利用できる.

  • CountDownLatchの使用例を次に示します.
    public class Test {
         public static void main(String[] args) {   
             final CountDownLatch latch = new CountDownLatch(2);
    
             new Thread(){
                 public void run() {
                     try {
                         System.out.println("   "+Thread.currentThread().getName()+"    ");
                        Thread.sleep(3000);
                        System.out.println("   "+Thread.currentThread().getName()+"    ");
                        latch.countDown();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                 };
             }.start();
    
             new Thread(){
                 public void run() {
                     try {
                         System.out.println("   "+Thread.currentThread().getName()+"    ");
                         Thread.sleep(3000);
                         System.out.println("   "+Thread.currentThread().getName()+"    ");
                         latch.countDown();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                 };
             }.start();
    
             try {
                 System.out.println("  2        ...");
                latch.await();
                System.out.println("2          ");
                System.out.println("       ");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
         }
    }
    

    CyclicBarrierの使用例を次に示します.
    public class Test {
        public static void main(String[] args) {
            int N = 4;
    
            CyclicBarrier barrier  = new CyclicBarrier(N,new Runnable() {
                @Override
                public void run() {
                    System.out.println("    "+Thread.currentThread().getName());   
                }
            });
    
            for(int i=0;i

    本稿では,Semaphore,CyclicBarrier,CountDownLatch神器に関する面接問題の解析を参照する