スレッド同期ツールクラス


同期ツールクラスには、信号量(Semaphore)、フェンス(barrier)、ロック(CountDownLatch)が含まれます.
 
閉鎖(CountDownLatch)
public class RunMain {
	public long timeTasks(int nThreads, final Runnable task) throws InterruptedException {
		final CountDownLatch startGate = new CountDownLatch(1);
		final CountDownLatch endGate = new CountDownLatch(nThreads);

		for (int i = 0; i < nThreads; i++) {
			Thread t = new Thread() {
				public void run() {
					try {
						startGate.await();
						try {
							task.run();
						} finally {
							endGate.countDown();
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

				};
			};
			t.start();
		}
		long start = System.nanoTime();
		startGate.countDown();
		endGate.await();
		long end = System.nanoTime();
		return end - start;
	}

}

 
FutrureTask
FutureTaskは閉鎖することもでき、FutureTaskが表す計算はCallableによって実現され、結果を生成できるRunnableに相当し、以下の3中状態にすることができる.
  • 運転待ち
  • は、
  • を実行しています.
  • 運転完了:計算のすべての可能な終了方式には、正常終了、キャンセルによる終了、異常による終了などが含まれることを示す.FutureTaskが完了状態に入ると、この状態では永遠に停止します.

  •     Future.getの動作はタスクのステータスに依存し、タスクが完了した場合、getはすぐに結果を返します.そうしないと、完了ステータスがブロックされ、結果が戻ったり、異常が放出されたりします.FutureTaskは計算結果を計算を実行するスレッドからこの結果を取得するスレッドに伝達し、FutureTaskの仕様は、この伝達プロセスが結果の安全な公開を実現することを保証する.
    public class RunMain {
    
    	private FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
    		public String call() throws Exception {
    			System.err.println(" ");
    			Thread.sleep(3000);
    			return " ";
    		};
    	});
    
    	private Thread thread = new Thread(future);
    
    	public void start() {
    		thread.start();
    	}
    
    	public String get() throws InterruptedException, ExecutionException {
    			return future.get();
    	}
    	
    	public static void main(String[] args) throws InterruptedException, ExecutionException{
    		RunMain run  = new RunMain();
    		run.start();
    		System.out.println(run.get());
    	}
    }

     
    信号量(Semaphore)
    カウント信号量は、特定のリソースに同時にアクセスする操作の数を制御するために使用され、または特定の操作を同時に実行する数を制御するために使用され、カウント信号量は、あるリソースプールを実現したり、コンテナに境界を適用したりするために使用されてもよい.
    public class RunMain<T> {
    	private Set<T> set;
    	private Semaphore sem;
    
    	public RunMain(int bound) {
    		set = Collections.unmodifiableSet(new HashSet<T>());
    		sem = new Semaphore(bound);
    	}
    
    	public boolean add(T t) throws InterruptedException {
    		sem.acquire();
    		boolean boo = false;
    		try {
    			boo = set.add(t);
    			return boo;
    		} finally {
    			if (!boo)
    				sem.release();
    		}
    	}
    
    	public boolean remove(T t) {
    		boolean boo = set.remove(t);
    		if (boo)
    			sem.release();
    		return boo;
    
    	}
    }

     
    フェンス
    すべてのスレッドは、実行を続行するためにフェンスの位置に同時に到達する必要があります.ロックはイベントを待つために使用され、フェンスは他のスレッドを待つために使用されます.
    CyclicBarrierは,並列反復アルゴリズムにおいて非常に有用な,一定数の参加者をフェンス位置に反復的に集約することができる.
    コード:http://www.cnblogs.com/dolphin0520/p/3920397.html
    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<N;i++)
                new Writer(barrier).start();
        }
        static class Writer extends Thread{
            private CyclicBarrier cyclicBarrier;
            public Writer(CyclicBarrier cyclicBarrier) {
                this.cyclicBarrier = cyclicBarrier;
            }
     
            @Override
            public void run() {
                System.out.println(" "+Thread.currentThread().getName()+" ...");
                try {
                    Thread.sleep(5000);      // 
                    System.out.println(" "+Thread.currentThread().getName()+" , ");
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }catch(BrokenBarrierException e){
                    e.printStackTrace();
                }
                System.out.println(" , ...");
            }
        }
    }