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();
	        }
	   }
}
发布了64 篇原创文章 · 获赞 11 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Summer_i/article/details/92584520