【多线程_并发工具】 闭锁-CountDownLacth

主要的例子,参考自博客:http://blog.csdn.net/lmj623565791/article/details/26626391。


先看一个问题:

每天起早贪黑的上班,父母每天也要上班,话说今天定了个饭店,一家人一起吃个饭,通知大家下班去饭店集合。假设:3个人在不同的地方上班,必须等到3个人到场才能吃饭,用
程序如何实现呢?

不正确的实现1.

    package com.zhy.concurrency.latch;  
      
    public class Test1  
    {  
        /** 
         * 模拟爸爸去饭店 
         */  
        public static void fatherToRes()  
        {  
            System.out.println("爸爸步行去饭店需要3小时。");  
        }  
      
        /** 
         * 模拟我去饭店 
         */  
        public static void motherToRes()  
        {  
            System.out.println("妈妈挤公交去饭店需要2小时。");  
        }  
      
        /** 
         * 模拟妈妈去饭店 
         */  
        public static void meToRes()  
        {  
            System.out.println("我乘地铁去饭店需要1小时。");  
        }  
      
        /** 
         * 模拟一家人到齐了 
         */  
        public static void togetherToEat()  
        {  
            System.out.println("一家人到齐了,开始吃饭");  
        }  
      
        public static void main(String[] args)  
        {  
            fatherToRes();  
            motherToRes();  
            meToRes();  
            togetherToEat();  
        }  
    }  

输出结果:

    爸爸步行去饭店需要3小时。  
    妈妈挤公交去饭店需要2小时。  
    我乘地铁去饭店需要1小时。  
    一家人到齐了,开始吃饭  

所有人的到达应该并行的而不是穿行的,所以需要并发。


不正确的实现2:

    public static void main(String[] args)  
        {  
            new Thread()  
            {  
                public void run()  
                {  
                    fatherToRes();  
                };  
            }.start();  
            new Thread()  
            {  
                public void run()  
                {  
                    motherToRes();  
                };  
            }.start();  
            new Thread()  
            {  
                public void run()  
                {  
                    meToRes();  
                };  
            }.start();  
              
            togetherToEat();  
        }  

输出结果:

    一家人到齐了,开始吃饭  
    我乘地铁去饭店需要1小时。  
    妈妈挤公交去饭店需要2小时。  
    爸爸步行去饭店需要3小时。  

开始吃饭一定要等到所有人到达才行。


正确的实现1.

    private static volatile int i = 3;  
      
        public static void main(String[] args)  
        {  
      
            new Thread()  
            {  
                public void run()  
                {  
                    fatherToRes();  
                    i--;  
                };  
            }.start();  
            new Thread()  
            {  
                public void run()  
                {  
                    motherToRes();  
                    i--;  
                };  
            }.start();  
            new Thread()  
            {  
                public void run()  
                {  
                    meToRes();  
                    i--;  
                };  
            }.start();  
      
            while (i != 0);  
            togetherToEat();  
        }  
这样做对CPU的负荷大。


正确的实现2:

public class demo {
	
	public static CountDownLatch latch = new CountDownLatch(3);
	
	public static void fatherGoRes(){
		System.out.println("父亲到需要三个小时");
	}
	
	public static void motherGoRes(){
		System.out.println("母亲到达需要2个小时");
	}
	
	public static void sonGoRes(){
		System.out.println("儿子到达需要1个小时");
	}
	
	public static void togetherToEat(){
		System.out.println("人都到期了,准备吃饭。");
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated meth奥od stub
		new Thread(new Runnable() {
			
			public void run() {
				// TODO Auto-generated method stub
				fatherGoRes();
				//递减锁存器的计数,如果计数到达零,则释放所有等待的线程
				latch.countDown();
			}
		}).start();
		
		new Thread(new Runnable() {
			
			public void run() {
				motherGoRes();
				latch.countDown();
			}
		}).start();
		
		new Thread(new Runnable() {
			
			public void run() {
				sonGoRes();
				//递减锁存器的计数,如果计数到达零,则释放所有等待的线程
				latch.countDown();
			}
		}).start();
		
		//使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断
		try {
			latch.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		togetherToEat();
	}

}


所以什么是闭锁呢?

《Java 并发编程实践》中解释道:闭锁的作用类似于一扇门:在闭锁到达结束状态之前,这扇门一直是关闭着的,不允许任何线程通过,当到达结束状态时,这扇门会打开并允许所有的线程通过。且当门打开了,就永远保持打开状态。


他的使用场景:

1.确保某个计算在其需要的所有资源都被初始化之后才继续执行

2.确保某个服务再其依赖的所有其他服务都已经启动后才启动。

3.等待某个操作的所有参入这都要就绪在继续执行。


CountDownLatch的主要方法如下:

 void await() 
          使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。 
 boolean await(long timeout, TimeUnit unit) 
          使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。 
 void countDown() 
          递减锁存器的计数,如果计数到达零,则释放所有等待的线程。 
 long getCount() 
          返回当前计数。 
 String toString() 
          返回标识此锁存器及其状态的字符串。 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值