J.U.C AQS(abstractqueuedssynchronizer--同步器)

时间:2019-04-15
本文章向大家介绍J.U.C AQS(abstractqueuedssynchronizer--同步器),主要包括J.U.C AQS(abstractqueuedssynchronizer--同步器)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

J.U.C AQS(abstractqueuedssynchronizer--同步器)

  同步器是用来构建锁和其他同步组件的基础框架,它的实现主要依赖一个int成员变量来表示同步状态以及通过一个FIFO队列构成等待队列

CountDownLatch

  用来控制一个线程等待多个线程。维护了一个计数器cnt,每次调用countDown()方法,会是cnt的计数值减1,减到0 的时候,那些因为调用await()而等待的线程被唤醒。

package ConcurrentExemple;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchExemple {
    public static void main (String[]args)throws InterruptedException{
        final int totalThread=10;
        CountDownLatch countDownLatch=new CountDownLatch(totalThread);
        ExecutorService executorService= Executors.newCachedThreadPool();
        for(int i=0;i<10;i++){
            executorService.execute(()->{
                System.out.println(Thread.currentThread().getName()+"开始运行");
                try{
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"已经运行完");
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
        System.out.println("休眠线程唤醒");
        executorService.shutdown();
    }
}

CyclicBarrier

  用来控制多个线程相互等待,等到所有的线程都到达时,这些线程才会继续执行。

​ 它同CountDownLatch一样维护一个计数器cnt,每个线程调用一次await(),cnt减一,当cnt为0 的时候,所有的线程都到达,这时这些线程继续执行。CyclicBarrier 和 CountdownLatch 的一个区别是,CyclicBarrier 的计数器通过调用 reset() 方法可以循环使用,所以它才叫做循环屏障

package ConcurrentExemple;

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

public class CyclicBarrierExemple {
    public static void main(String[]args){
        final int totalThread=10;
        CyclicBarrier cyclicBarrier=new CyclicBarrier(totalThread);
        ExecutorService executorService= Executors.newCachedThreadPool();
        for(int i=0;i<totalThread;i++){
            executorService.execute(()->{
                System.out.println(Thread.currentThread().getName()+"begin");
                try{
                    cyclicBarrier.await();
                }catch (InterruptedException| BrokenBarrierException e){
        e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"end");
        });

        }
        executorService.shutdown();
        }
        }

Semaphore

  信号量Semaphore 类似于操作系统中的信号量,可以控制对互斥资源的访问线程数

​ 以下代码模拟了对某个服务的并发请求,每次只能有 3 个客户端同时访问,请求总数为 10。

package ConcurrentExemple;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemaphoreExemple {
    public static void main(String[]args){
        int customer=3;
        int totalThread=10;
        Semaphore semaphore=new Semaphore(customer);
        ExecutorService executorService= Executors.newCachedThreadPool();
        for(int i=0;i<totalThread;i++){
            executorService.execute(()->{
                try {
                semaphore.acquire();
                System.out.println(semaphore.availablePermits()+" ");
                Thread.sleep(3000);
                }catch (InterruptedException e){
                e.printStackTrace();
            }finally {
                    semaphore.release();
                }
            });

        }
        executorService.shutdown();
    }
}