JUC三个并发锁CountDownLatch、CyclicBarrier、Semaphore示范和解释
  TEZNKK3IfmPf 2023年11月13日 19 0

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();
    }
}

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

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();
    }
}

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

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();
    }
}

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

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   24天前   51   0   0 java
  TEZNKK3IfmPf   2024年05月31日   55   0   0 java
TEZNKK3IfmPf