CountDownLatch、CyclicBarrier、Semaphore

{
"title":"AQS相关",
"date":2020-05-21T09:16:43+08:00,
"draft":true,
"tags":["CountDownLatch、CyclicBarrier、Semaphore"],
"comments":true,
"share":true
}

  1. AQS 简单介绍

  2. AQS 原理

  3. CountDownLatch相关

CountDownLatch:让一些线程阻塞直到另外一些完成后才被唤醒。代码演示。

CountDownLatch主要有两个方法,当一个或多个线程调用await()方法时,调用线程会被阻塞。
其他线程调用countDown()方法计数器减1(调用countDown方法时线程不会阻塞),当计数器的值变为0,
因调用await方法被阻塞的线程会被唤醒,继续执行。

package com.xpf.Interview.juc.other;

import java.util.concurrent.CountDownLatch;

/**
 * @Author: Xia
 * @Date: 2020/5/21 9:30
 * @Email:x2358114512@163.com
 代码实现:等for里的线程完成结束后,main线程才能执行。
 */
public class T {
    public static void main(String[] args) {
        notcountDownLatch();
        countDownLatch();
    }

    private static void countDownLatch() {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"线程完成任务,回家");
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
        try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println(Thread.currentThread().getName()+"线程完成任务,回家");
    }

    private static void notcountDownLatch() {
        for(int i = 0;i<5;i++){
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"线程完成任务,回家");
            },String.valueOf(i)).start();
        }
        System.out.println(Thread.currentThread().getName()+"线程完成任务,回家");
    }
}

notcountDownLatch()函数的结果:
            0线程完成任务,回家
            3线程完成任务,回家
            1线程完成任务,回家
            main线程完成任务,回家
            2线程完成任务,回家
            4线程完成任务,回家

countDownLatch()函数的结果:   
           0线程完成任务,回家
            1线程完成任务,回家
            2线程完成任务,回家
            4线程完成任务,回家
            3线程完成任务,回家
            main线程完成任务,回家
  1. CyclicBarrier相关

CyclicBarrier的字面意思是可循环(Cyclic)使用的屏障(barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫做同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。线程进入屏障通过CyclicBarrier的await()方法。代码演示。
1. 线程进入屏障通过CyclicBarrier的await()方法。
2. 构造方法:public CyclicBarrier(int parties, Runnable barrierAction)
Runnable barrierAction指的是被阻塞的哪个线程

package com.xpf.Interview.juc.other;

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

/**
 * @Author: Xia
 * @Date: 2020/5/21 9:30
 * @Email:x2358114512@163.com
 */
public class T {
    public static void main(String[] args) {
        cyclicBarrier();
    }

    private static void cyclicBarrier() {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5,() -> {
            System.out.println(Thread.currentThread().getName()+"线程:前5个线程完成后,最后才会完成此线程");
        });

        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"线程:完成任务");
                try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); }
            },String.valueOf(i)).start();
        }
    }
}

cyclicBarrier()函数执行结果:
            0线程:完成任务
            2线程:完成任务
            3线程:完成任务
            1线程:完成任务
            4线程:完成任务
            4线程:前5个线程完成后,最后才会完成此线程
  1. Semaphore相关

引出问题:之前的案列都是多线程访问同一份共享资源;对于多线程访问多份共享资源那怎么处理?

    这里就可以引出Semaphore。

Semaphore(信号量)的作用:用于多线程调用多个共享资源的互斥使用,另外也可以用于并发线程数的控制。



package com.xpf.Interview.juc.other;

import java.sql.Time;
import java.util.concurrent.*;

/**
 * @Author: Xia
 * @Date: 2020/5/21 9:30
 * @Email:x2358114512@163.com
 模拟5个车(5个线程)抢3个车位(3个资源)
 */
public class T {
    public static void main(String[] args) {
        semaphore();
    }

    private static void semaphore() {
        Semaphore semaphore = new Semaphore(3);  //模拟3个停车位(资源)

        for (int i = 0; i < 5; i++) {            //模拟5部汽车(线程)
            new Thread(() -> {
                try{
                    semaphore.acquire();   //当前线程抢到资源
                    System.out.println(Thread.currentThread().getName()+"线程:抢到停车位");
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(Thread.currentThread().getName()+"线程:2秒后离开停车位");
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    semaphore.release();   //当前线程释放资源
                }
            },String.valueOf(i)).start();
        }
    }
}



semaphore()函数执行结果:    
                0线程:抢到停车位
                1线程:抢到停车位
                2线程:抢到停车位
                0线程:2秒后离开停车位
                2线程:2秒后离开停车位
                3线程:抢到停车位
                4线程:抢到停车位
                1线程:2秒后离开停车位
                3线程:2秒后离开停车位
                4线程:2秒后离开停车位
全部评论

相关推荐

头像
11-06 10:58
已编辑
门头沟学院 嵌入式工程师
双非25想找富婆不想打工:哦,这该死的伦敦腔,我敢打赌,你简直是个天才,如果我有offer的话,我一定用offer狠狠的打在你的脸上
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务