JAva同時同期ツール類二の信号灯semaphore

4088 ワード

JAvaの信号は、複数のスレッドが同じリソースに同時にアクセスする操作の数を制御することができ、この文の重点は「制御」の2文字にあることに注意してください.すなわち、あるコンテナに境界制限を加えることもできるし、あるリソースのプール化を実現することもできる.例えば、スレッドプールで最大5つのスレッドの実行を制限し、5つ以上のスレッドが同時にスレッドプールにアクセスする場合、必ず1つのスレッドがブロック待機状態にある.境界数を制御することで、スレッドがメモリを消費しすぎてメモリ不足の問題を回避できます.その実装は、境界コンテナ内で実行されるアクセス許可permitのセットを介して行われる.例えばデパートのガレージは、駐車スペースが限られていますが、ここで駐車する数が駐車スペースより大きい場合は、一部の車両がガレージの中の車が先に出るのを待たなければなりません.その間、ずっと渋滞しています.次のコードを見てください.
import java.util.concurrent.Semaphore;

/**
 *
 * @author Jerry
 * @date 2017/12/24 0024
 */
public class Garage {

    public static void main(String[] args) {
        Semaphore semaphore=new Semaphore(3);//       3  
        System.out.println("        ......");
        for (int i=1;i<=5;i++){
            Thread thread=new Thread(new Car(" A"+i,semaphore));
            thread.start();
        }
    }
    static class Car implements Runnable{
        private String name;
        private Semaphore semaphore;

        public Car(String name, Semaphore semaphore) {
            this.name = name;
            this.semaphore = semaphore;
        }

        @Override
        public void run() {
            try {
                semaphore.acquire();//    ,     
                System.out.println("+ "+name+"    ");
                parking();
                semaphore.release();//    ,     
                System.out.println("- "+name+"      ");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        private void parking() {
            System.out.println(name+"   ");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

運転結果は以下の通りで、プログラムでは駐車スペースが3に制限されていますが、駐車数が5であることは、前の車両が駐車スペースを空けてから入庫するまで2台の車が待機していることを意味します.
        ......
+  A1    
 A1   
+  A2    
 A2   
+  A3    
 A3   
-  A1      
+  A4    
+  A5    
-  A2      
 A5   
 A4   
-  A3      
-  A5      
-  A4