JUC三个并发锁CountDownLatch、CyclicBarrier、Semaphore示范和解释

JUC三个并发锁CountDownLatch、CyclicBarrier、Semaphore示范和解释

三个都位于java.util.concurrent下,并发锁,内部都是利用抽象类Sync实现的,做计数器的时候使用的CompareAndSet对Sync内部的成员变量整数state做增减实现,另外支持公平锁和非公平锁,默认是非公平锁NonFairSync

CountDownLatch 计数器锁

线程来调用countdown()让计数器递减(CAS,CompareAndSet),直到0的时候await()函数堵塞的会被放行

package lock;

import java.util.concurrent.CountDownLatch;

/**
 * CountDownLatchDemo 示范
 * 构造方法传入一个计数器
 * countdown()让计数器减1
 * 直到计数器被减到0时 await()的等待会被放行
 */
public class CountDownLatchDemo {
    public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(2);
        Thread thread = new Thread(()->{
            try {
                countDownLatch.await();
                System.out.println(Thread.currentThread().getName()+"通过countdown锁,执行代码");
            }catch (Exception e){
                e.printStackTrace();
            }

        },"thread");
        Thread t1 = new Thread(()-> {
            try {
                Thread.sleep(1000);
                countDownLatch.countDown();
                System.out.println(Thread.currentThread().getName()+"执行了countdown");
            }catch (Exception e){
                e.printStackTrace();
            }
        },"t1");
        Thread t2 = new Thread(()-> {
            try {
                countDownLatch.countDown();
                System.out.println(Thread.currentThread().getName()+"执行了countdown");
            }catch (Exception e){
                e.printStackTrace();
            }
        },"t2");
        thread.start();
        t1.start();
        t2.start();
    }
}

在这里插入图片描述

CyclicBarrier 循环珊栏锁

线程来调用await()声明自己已经执行到了珊栏等待其他线程到了再执行,让计数器递减(CAS,CompareAndSet),直到0的时候该堵塞的所有线程全部会被放行

package lock;

import java.util.Random;
import java.util.concurrent.CyclicBarrier;

/**
 * 循环珊栏示范
 * 构造方法传入总共要等几个线程await才能通过珊栏
 * await()告知锁我已经到达珊栏进行等待了
 * 一旦要求的所有线程到达了珊栏进行等待即可放行通过,通过后珊栏会被自动重置掉,能循环使用
 */
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        Random random = new Random();
        CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
        Thread t1 = new Thread(()->{
            for (;;){
                try {
                    Thread.sleep(random.nextInt(1000));
                    System.out.println(Thread.currentThread().getName()+"等待");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getName()+"越过了珊栏,执行");
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        },"t1");
        Thread t2 = new Thread(()->{
            for (;;){
                try {
                    Thread.sleep(random.nextInt(1000));
                    System.out.println(Thread.currentThread().getName()+"等待");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getName()+"越过了珊栏,执行");
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        },"t2");
        t1.start();
        t2.start();
    }
}

在这里插入图片描述

Semaphore 信号量锁

线程来调用aquire()让计数器递减(CAS,CompareAndSet),拿到了信号量就返回了继续执行,如果没拿到可以一直堵塞在那等待拿到才继续执行,另外也可以手动调用release()来添加信号量,让计数器自增。

package lock;

import java.util.Random;
import java.util.concurrent.Semaphore;

/**
 * Semaphore信号量锁示范
 * 构造方法传入总共多少个信号量
 * acquire()请求拿一个信号量
 * release()添加一个信号量
 */
public class SemaphoreDemo {
    public static void main(String[] args) {
        Random random = new Random();
        Semaphore semaphore = new Semaphore(2);
        Thread t1 = new Thread(()->{
            for (;;){
                try {
                    Thread.sleep(random.nextInt(2000));
                    System.out.println(Thread.currentThread().getName()+"等待");
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"获得了信号量,执行代码");
                    Thread.sleep(random.nextInt(2000));
                    System.out.println(Thread.currentThread().getName()+"执行完了代码,释放信号量");
                    semaphore.release();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        },"t1");
        Thread t2 = new Thread(()->{
            for (;;){
                try {
                    Thread.sleep(random.nextInt(2000));
                    System.out.println(Thread.currentThread().getName()+"等待");
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"获得了信号量,执行代码");
                    Thread.sleep(random.nextInt(2000));
                    System.out.println(Thread.currentThread().getName()+"执行完了代码,释放信号量");
                    semaphore.release();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        },"t2");
        t1.start();
        t2.start();
    }
}

在这里插入图片描述

posted @ 2021-09-09 10:23  HumorChen99  阅读(0)  评论(0编辑  收藏  举报  来源