Countdownlatch , CyclicBarrier , Semaphore类

1.**

countdownlatch

**
多数用于任务拆分
2.

public class CountDownLatchExample {
 	 public static void main(String[] args) throws InterruptedException {
    CountDownLatch latch = new CountDownLatch(20);
    Service service = new Service(latch);
    Runnable task = () -> service.exec();
   	for (int i = 0; i < 20; i++) {
      Thread thread = new Thread(task);
      thread.start();
	}
	    System.out.println("主线程等待. ");
	    latch.await();
	    System.out.println("主线程完成等待. ");
	}
}
  public class Service {
	  private CountDownLatch latch;
	  public Service(CountDownLatch latch) {
	    this.latch = latch;
	  }
  public void exec() {
    try {
      System.out.println(Thread.currentThread().getName() + " execute task. ");
      sleep(2);
      System.out.println(Thread.currentThread().getName() + " finished task. ");
    } finally {
      latch.countDown();
    }
  }
  private void sleep(int seconds) {
    try {
      TimeUnit.SECONDS.sleep(seconds);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

3.输出

> Thread-0 execute task. 
Thread-1 execute task. 
Thread-2 execute task. 
Thread-3 execute task. 
Thread-4 execute task. 
主线程等待. 
Thread-0 finished task. 
Thread-4 finished task. 
Thread-3 finished task. 
Thread-1 finished task. 
Thread-2 finished task. 
主线程完成等待.

4.适合任务拆分,比如 一个老板视察工作, 三个工人干活,三个工作都完成工作之后,老板再来视察
5.这样使用countdownlatch比较合适
6.提高了任务效率, 多个线程并发执行不同任务,主线程等待所有任务都执行完 才会执行

总结 : await()阻塞主线程, 做减法 , 计数器减为0的时候,主线程才会走 在最后等,

**

CyclicBarrier

**
总结 : await()阻塞 做加法,加到一定程度, 那么主程序才会走 在线程中间等,有一个线程在等待执行最后的东西

 public class Test  {
	    ExecutorService fi = Executors.newFixedThreadPool(5);
	    public static void main(String[] args) throws InterruptedException {
	       final CyclicBarrier barrier  = new CyclicBarrier(50, new Runnable() {
	            @Override
	            public void run() {
	                System.out.println("集齐东西执行最后任务");
	            }
	        });
	        for(int i = 0 ; i< 50;i++){
	            final int r = i;
	            new Thread(new Runnable() {
	                @Override
	                public void run() {
	                    System.out.println(r+"开始集齐东西"+Thread.currentThread().getName());
	                    try {
	                        barrier.await();
	                    } catch (InterruptedException e) {
	                        e.printStackTrace();
	                    } catch (BrokenBarrierException e) {
	                        e.printStackTrace();
	                    }
	                }
	            }).start();
	        }
	        System.out.println("开始集齐东西"+Thread.currentThread().getName());
	    }
}

输出

0开始集齐东西Thread-0
1开始集齐东西Thread-1
2开始集齐东西Thread-2
3开始集齐东西Thread-3
4开始集齐东西Thread-4
5开始集齐东西Thread-5
6开始集齐东西Thread-6
7开始集齐东西Thread-7
8开始集齐东西Thread-8
9开始集齐东西Thread-9
10开始集齐东西Thread-10
11开始集齐东西Thread-11
12开始集齐东西Thread-12
13开始集齐东西Thread-13
14开始集齐东西Thread-14
15开始集齐东西Thread-15
16开始集齐东西Thread-16
17开始集齐东西Thread-17
18开始集齐东西Thread-18
19开始集齐东西Thread-19
20开始集齐东西Thread-20
21开始集齐东西Thread-21
22开始集齐东西Thread-22
23开始集齐东西Thread-23
24开始集齐东西Thread-24
25开始集齐东西Thread-25
26开始集齐东西Thread-26
27开始集齐东西Thread-27
28开始集齐东西Thread-28
29开始集齐东西Thread-29
30开始集齐东西Thread-30
31开始集齐东西Thread-31
32开始集齐东西Thread-32
33开始集齐东西Thread-33
34开始集齐东西Thread-34
35开始集齐东西Thread-35
36开始集齐东西Thread-36
37开始集齐东西Thread-37
38开始集齐东西Thread-38
39开始集齐东西Thread-39
49开始集齐东西Thread-49
40开始集齐东西Thread-40
48开始集齐东西Thread-48
47开始集齐东西Thread-47
46开始集齐东西Thread-46
45开始集齐东西Thread-45
44开始集齐东西Thread-44
43开始集齐东西Thread-43
42开始集齐东西Thread-42
41开始集齐东西Thread-41
集齐东西执行最后任务

**

semaphore

**
lock和 synchronized 默认是非公平锁, 非公平锁效率高 (可以加塞)

        Semaphore semaphore = new Semaphore(3,false);   

总结 : 信号量, 多个线程抢多个资源 可以代替 lock , synchronized
1.多个共享资源互斥使用
2.并发线程数控制
举个例子 Semaphore semaphore = new Semaphore(3,false); 可以当停车场的车位 只有三个,
线程有6个 ,可以当做是车
semaphore.acquire(); 代表一部车占位了,
semaphore.release(); 释放停车位 最好放在finally里面
值是可以伸缩的

  public class Test{
      public static void main(String[] args) throws InterruptedException {
		 final Semaphore semaphore = new Semaphore(30,true);
	        for(int i = 0 ; i < 180 ; i++){
	            new Thread(new Runnable() {
	                @Override
	                public void run() {
	                    try {
	                        semaphore.acquire();
	                        System.out.println("占用停车位 "+ Thread.currentThread().getName());
	                        Thread.sleep(3000);
	                        System.out.println("睡三秒离开车位 "+ Thread.currentThread().getName());
	                    } catch (InterruptedException e) {
	                        e.printStackTrace();
	                    }finally {
	                        semaphore.release();
	                    }
	                }
	            }).start();
	        }
	   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CountDownLatch 是一个计数器,它可以让一个或多个线程等待其他线程执行完毕后再继续执行。它的主要方法是 countDown() 和 await(),其中 countDown() 用于计数减一,await() 用于等待计数器变为0。与 CountDownLatch 相比,CyclicBarrier 的主要区别在于它可以重复使用,而且所有线程必须同时到达栅栏处才能继续执行后续任务。CyclicBarrier 的重要方法是 await(),并且可以通过构造方法传入一个 Runnable,在所有线程都到达栅栏状态时优先执行该动作。CyclicBarrier 内部使用 ReentrantLock 和 Condition 实现等待和唤醒的功能,通过维护一个 count 变量来记录还有多少个线程没有到达栅栏处。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [CountDownLatchCyclicBarrier](https://blog.csdn.net/weixin_44442186/article/details/123985119)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [JUC多线程:CountDownLatchCyclicBarrierSemaphore同步器原理总结](https://blog.csdn.net/a745233700/article/details/120688546)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值