zoukankan      html  css  js  c++  java
  • java并发之CountDownLatch

    CountDownLatch是java同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数num赋予CountDownLatch的构造函数,表示需要同步这num个线程,当这些线程运行到同步点时,对CountDownLatch调用CountDown()方法,使得num-1,当num减为0时,表示所有需要同步的线程均到达同步点,此时被CountDownLatch的await()方法阻塞的线程开始执行。

    CountDownLatch是闭锁的一种实现,闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态。它的作用相当于一扇门:在闭锁到达结束状态之前,这扇门始终是关闭的,而且没有任何线程可以通过,当到达结束状态时,这扇门就会打开并允许所有的线程通过。当闭锁到达结束状态后,将不会再改变状态,因此这扇门将永远保持打开状态。闭锁可以用来确保某些活动都完成后才继续执行,比如:

      1.确保某个计算在其需要的所有资源都被初始化之后才继续执行。二元闭锁(包括两个状态)可以用来表示“资源R已经被初始化”,而所有需要R的操作都必须在这个闭锁上等待。

      2.确保某个服务在其依赖的所有其它服务都已经启动之后才启动。每个服务都有一个相关的二元闭锁。当启动服务s时,将首先在s依赖的其它服务的闭锁上等待,在所有依赖的服务都启动后会释放闭锁s,这样其它依赖s的服务才能继续执行。

      3.等待直到某个操作的所有参与者(比如,在多玩家游戏中的所有玩家)都就绪再继续执行。在这种情况中,当所有玩家都准备就绪时,闭锁将到达结束状态。

    下面是一个示例程序,这个程序计算四个数的和:

    思路是把四个数分为两组,分别计算和,然后再对两组的和进行求和,代码如下:

    package com.test;
    
    import java.util.concurrent.CountDownLatch;
    
    public class CountDownLatchTest {
    	static class Worker extends Thread{
    		private CountDownLatch count;
    		private int left;
    		private int right;
    		private int result;
    		public Worker(CountDownLatch count, int left,int right) {
    			this.count = count;
    			this.left = left;
    			this.right = right;
    		}
    
    		@Override
    		public void run() {
    			synchronized(count){
    				System.out.print(Thread.currentThread().getName()+" : ");
    				result = left+right;
    				System.out.println("Partial result: "+result);
    				count.countDown();
    			}
    		}
    		
    		public int getResult(){
    			return result;
    		}
    	}
    	
    	public static void main(String[] args) throws Exception {	//计算1+2+3+4
    		CountDownLatch latch = new CountDownLatch(2);
    		Worker worker = new Worker(latch,1,2);
    		Worker worker2 = new Worker(latch,3,4);
    		worker.start();
    		worker2.start();
    		
    		System.out.println("Main waiting!!");
    		latch.await();
    		System.out.println("Waiting end,Result is: "+(worker.getResult()+worker2.getResult()));
    	}
    }
    

    使用FutureTask的代码:

    package com.test;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    class Worker implements Callable<Integer> {
    	private int hours = 12;
    	private int amount;
    	
    	@Override
    	public Integer call() throws Exception {
    		while(hours>0){
    			amount++;
    			System.out.println("I'm working......"+amount);
    			hours--;
    			Thread.sleep(100);
    		}
    		return amount;
    	}
    	
    }
    
    public class FutureTaskTest {
    	public static void main(String[] args) {
    		Worker worker = new Worker();
    		FutureTask<Integer> boss = new FutureTask<Integer>(worker);
    		new Thread(boss).start();
    		//System.out.println("hello");
    		//System.out.println(boss.isDone());
    		while(!boss.isDone()){
    			try {
    				System.out.println("看工人做完了没..........");
    				Thread.sleep(100);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		int amount;
    		try{
    			amount = boss.get();
    			System.out.println("工作完成"+amount);
    		}catch(InterruptedException e){
    			e.printStackTrace();
    		} catch (ExecutionException e) {
    			e.printStackTrace();
    		}
    	}
    }
    

      

  • 相关阅读:
    BZOJ 3529 数表
    BZOJ 3832 Rally
    BZOJ 1086 王室联邦
    BZOJ 2738 矩阵乘法
    2656565
    小L的区间求和
    小L的直线
    Co-prime 杭电4135
    POJ 跳蚤
    B
  • 原文地址:https://www.cnblogs.com/lxk2010012997/p/5404317.html
Copyright © 2011-2022 走看看