AQS-tools

2019-12-03  本文已影响0人  sizuoyi00

Semaphore

semaphore:控制访问特定资源的线程数目,一次开启指定数量的线程处理
使用场景:资源访问,服务限流

semaphore 公共资源池 共享模式 非公平锁 clh双向队列
公共资源没有了则入队操作:头尾节点为null,先初始化,然后依次插入队列,双向队列更新前驱后继,更新头尾节点
入队后操作:将状态失效的队列删除,cas更新状态,下次自旋新状态会进入到一个方法,该方法作用为阻塞当前线程 以此实现限流

共享模式释放工作资源:顺序唤醒阻塞队列中的线程,不会全部唤醒,除非队列为广播状态,具体唤醒个数与资源池中资源个数有关

demo

 public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(2);
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + ":aquire()" + System.currentTimeMillis());
                    Thread.sleep(1000);
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

结果形式为两条两条打印

Thread-0:aquire()1575217007802
Thread-1:aquire()1575217007802
Thread-2:aquire()1575217008803
Thread-3:aquire()1575217008803
Thread-4:aquire()1575217009804

Countdownlatch

CountDownLatch能够使一个线程等待其他线程完成各自的工作后再执行。
应用场景:excel多线程多sheet页解析,全部sheet页解析完成后才返回解析完成。原理与semaphore类似

demo:

public static void main(String[] args) throws InterruptedException {
        long now = System.currentTimeMillis();
        CountDownLatch countDownLatch = new CountDownLatch(2);

        new Thread(() -> {
            try {
                System.out.println("sheet1开始处理");
                Thread.sleep(2000);
                System.out.println("sheet1处理完毕");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
        }).start();

        new Thread(() -> {
            try {
                System.out.println("sheet2开始处理");
                Thread.sleep(1000);
                System.out.println("sheet2处理完毕");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
        }).start();

        //等待2个线程任务执行完毕,
        countDownLatch.await();
        System.out.println("sheet处理完毕:" + (System.currentTimeMillis() - now));
    }

CyclicBarrier

栅栏屏障,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
使用场景:多线程处理数据,最后合并计算结果的场景。

上一篇下一篇

猜你喜欢

热点阅读