并发工具类

CountDownLatch

让主线程等待一组事件发生后继续执行

CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

countDownLatch.countDown() //计数器减一
countDownLatch.await();  //线程等待,直到计数器为0

example

import java.util.concurrent.CountDownLatch;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(7);
        IntStream.rangeClosed(1, 7).forEach(i -> {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t" + i);
                countDownLatch.countDown();
            }, String.valueOf(i)).start();
        });
        countDownLatch.await();
        System.out.println("finish");

    }
}

CyclicBarrier

CyclicBarrier的功能和CountDownLatch相反,是做加法。(集齐7颗龙珠才能召唤神龙)

一般采用的构造函数

public CyclicBarrier(int parties, Runnable barrierAction) {
        if (parties <= 0) throw new IllegalArgumentException();
        this.parties = parties;
        this.count = parties;
        this.barrierCommand = barrierAction;
    }

即使当累计达到parties数目时,则执行runable。

example


import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> System.out.println("召唤神龙"));
        IntStream.rangeClosed(1, 14).forEach(i -> new Thread(() -> {
            System.out.println(i);
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }).start());
    }
}

1
4
2
6
3
5
7
召唤神龙
9
8
10
11
12
13
14
召唤神龙

Semaphore

1、用于多个共享资源的互斥使用

2、用于并发线程数的控制

Semaphore semaphore = new Semaphore(1);//相当于lock锁

semaphore就是有多个资源的lock,可以用餐桌理解,一个餐厅有固定数量的餐桌,来的人可以先获取到空的餐桌。当餐桌被分配光了以后,更多的人进来需要等待,直到前面的人离开。

example


import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

public class Main {

    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);//模拟三个座位
        IntStream.range(0, 6).forEach(i -> {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + ":占到座位");
                    TimeUnit.SECONDS.sleep(3);
                } catch (Exception e) {

                } finally {
                    System.out.println(Thread.currentThread().getName() + ":离开座位");
                    semaphore.release();
                }
            }, i + "线程").start();
        });
    }
}

0线程:占到座位
2线程:占到座位
1线程:占到座位
2线程:离开座位
0线程:离开座位
1线程:离开座位
4线程:占到座位
3线程:占到座位
5线程:占到座位
3线程:离开座位
5线程:离开座位
4线程:离开座位

posted @ 2020-07-27 14:03  刃牙  阅读(117)  评论(0编辑  收藏  举报