首页 > 其他分享 >CountDownLatch、CyclicBarrier、Semaphore

CountDownLatch、CyclicBarrier、Semaphore

时间:2024-05-13 17:53:21浏览次数:33  
标签:Thread Semaphore threadCount 线程 CountDownLatch CyclicBarrier

一、CountDownLatch
CountDownLatch是一个计数器类,用来控制线程等待其他线程执行完毕再继续执行。这个类通常用于主线程等待多个子线程完成任务后再进行下一步操作。CountDownLatch的实现基于AQS(AbstractQueuedSynchronizer),使用了共享锁的方式。
CountDownLatch的使用思路比较简单,首先创建一个CountDownLatch对象,并把需要等待的线程数量传入CountDownLatch的构造方法。然后在每个子线程完成任务时通过countDown()方法来减少计数器的值。当计数器变为0时,await()方法会返回,主线程就可以继续执行下一步操作。
代码示例:

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        int threadCount = 5;
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        for (int i = 0; i < threadCount ; i++) {
            new Thread(() -> {
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " 执行完毕");
                countDownLatch.countDown();
            }).start();
        }

        countDownLatch.await();
        System.out.println("所有线程执行完毕");
    }
}

以上代码中,我们创建了一个CountDownLatch对象,并传入需要等待的线程数量。然后通过for循环创建了5个子线程,每个子线程都会睡眠1秒钟,模拟执行任务。当每个子线程完成任务后,调用countDown()方法来减少计数器的值。最后在主线程中调用await()方法来等待所有子线程完成任务。
二、CyclicBarrier
CyclicBarrier也是一个很有用的同步工具类,它可以让一组线程到达某个屏障(也可以理解为关卡)时被阻塞,直到所有线程都到达该屏障时才能继续执行。CyclicBarrier和CountDownLatch的区别在于,CountDownLatch只能使用一次,而CyclicBarrier可以重复使用。

CyclicBarrier的实现也是基于AQS(AbstractQueuedSynchronizer),但是使用了独占锁的方式。CyclicBarrier的使用思路也比较简单,首先创建一个CyclicBarrier对象,并把需要等待的线程数量和到达该屏障时需要执行的动作(可选)传入CyclicBarrier的构造方法。当所有线程到达该屏障时,CyclicBarrier会自动调用之前设置的动作(如果有),然后所有线程就可以继续执行接下来的操作。
代码示例:

public class CyclicBarrierDemo {
    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
        int threadCount = 3;
        CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount, () -> System.out.println("所有线程到达屏障"));

        for (int i = 0; i < threadCount ; i++) {
            new Thread(() -> {
                try {
                    Thread.sleep(1000L);
                    System.out.println(Thread.currentThread().getName() + " 到达屏障");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getName() + " 继续执行");
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

我们创建了一个CyclicBarrier对象,并传入需要等待的线程数量和到达屏障时需要执行的动作。然后通过for循环创建了3个子线程,每个子线程都会睡眠1秒钟,并在到达屏障时调用await()方法。当所有子线程都到达屏障时,CyclicBarrier会自动执行之前设置的动作(输出“所有线程到达屏障”),然后所有线程就可以继续执行接下来的操作。
三、Semaphore
Semaphore是另一种常见的同步工具类,它可以限制同时访问某个共享资源的线程数量。Semaphore的实现也是基于AQS(AbstractQueuedSynchronizer),使用了共享锁的方式。

Semaphore的使用思路比较简单,首先创建一个Semaphore对象,并把该共享资源的数量传入Semaphore的构造方法。然后在每个需要访问该共享资源的线程中调用acquire()方法来获取访问权限,在使用完共享资源后再调用release()方法来释放访问权限。
代码示例:

public class SemaphoreDemo {
    public static void main(String[] args) {
        int threadCount = 10;
        Semaphore semaphore = new Semaphore(2);

        for (int i = 0; i < threadCount ; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + " 获取访问权限");
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName() + " 释放访问权限");
                }
            }).start();
        }
    }
}

我们创建了一个Semaphore对象,并传入该共享资源的数量。然后通过for循环创建了10个子线程,每个子线程需要获取访问权限才能执行,如果访问权限已满则需要等待其他线程释放访问权限。当使用完共享资源后,子线程需要调用release()方法来释放访问权限。

标签:Thread,Semaphore,threadCount,线程,CountDownLatch,CyclicBarrier
From: https://www.cnblogs.com/juyss/p/18189698

相关文章

  • java 多线程CountDownLatch
     CountDownLatch简介CountDownLatch 是Java中的一个同步工具类,可以用来确保一组线程等待其他线程完成各自工作后再继续执行。CountDownLatch的应用场景CountDownLatch可以被广泛应用于各种多线程协作的场景,例如:主线程等待多个子线程完成后再执行下一步操作。多个子任......
  • 信号量 semaphore的实现 -06
    1 semaphore的内核结构体注意:这是信号量,不是信号。在前面学习异步通知时,驱动程序给应用程序发信号。现在我们讲的信号量是一种同步、互斥机制。信号量的定义及操作函数都在Linux内核文件include\linux\semaphore.h中定义,如下: 初始化semaphore之后,就可以使用down函数或其他衍......
  • 10. Semaphore ||(信号量)
    信号量实现同步举个例子在这里司机启动车辆需要售票员关车门,售票员开车门需要司机到站停车。对于这两个线程来说需要设置两个semaphored=0;semaphorec=0;为什么呢,因为有执行顺序的问题,只有售票员关门时候才可以启动车辆,设置一个d=0,司机启动汽车时候,这个线程执行p(d)来检......
  • 实验4 信号量(Semaphores)
    要使用信号量,请先包含头文件<semaphore.h>sem_t:信号量的数据类型intsem_init(sem_t*sem,intpshared,unsignedintval);该函数第一个参数为信号量指针,第二个参数为信号量类型(一般设置为0),第三个为信号量初始值,第二个参数pshared为0时,该进程内所有线程可用,不为0时不同进......
  • 信号量(Semaphores)
    信号量与pv操作信号量信号量(Semaphore)是一种比互斥锁更强大的同步工具,它可以提供更加高级的方法来同步并发进程。AsemaphoreSisanintegervariablethat,apartfrominitialization(初始化),isaccessedonlythroughtwostandardatomicoperations:PVP:wait()......
  • 并发编程(Semaphore)
    Semaphore,信号量,它保存了一系列的许可(permits),每次调用acquire()都将消耗一个许可,每次调用release()都将归还一个许可特性Semaphore通常用于限制同一时间对共享资源的访问次数上,也就是常说的限流。下面我们一起来学习Java中Semaphore是如何实现的。类结构Semaphore中包含了一......
  • 并发编程(CyclicBarrier)
    CyclicBarrier是一个同步器,允许一组线程相互之间等待,直到到达某个公共屏障点(commonbarrierpoint),再继续执行CyclicBarrier与CountDownLatch异同都可以阻塞一组线程等待被唤醒CyclicBarrier是最后一个线程到达后会自动唤醒,而CountDownLatch需要显式调用countDown方法Cyc......
  • netcore 并发锁 多线程中使用SemaphoreSlim
    SemaphoreSlim是一个用于同步和限制并发访问的类,和它类似的还有Semaphore,只是SemaphoreSlim更加的轻量、高效、好用。今天说说它,以及如何使用,在什么时候去使用,使用它将会带来什么优势。代码的业务是:在多线程下进行数据的统计工作,简单点的说就是累加数据。1.首先我们建立一个程......
  • 面试官:实战中用过CountDownLatch吗?详细说一说,我:啊这
    写在开头在很多的面经中都看到过提问CountDownLatch的问题,正好我们最近也在梳理学习AQS(抽象队列同步器),而CountDownLatch又是其中典型的代表,我们今天就继续来学一下这个同步工具类!CountDownLatch有何作用?我们知道AQS是专属于构造锁和同步器的一个抽象工具类,基于它Java构造出了......
  • 今天我们来聊一聊Java中的Semaphore
    写在开头在上几天写《基于AQS手写一个同步器》时,很多同学留言说里面提到的Semaphore,讲得太笼统了,今天趁着周末有空,咱们就一起详细的学习和梳理一把Semaphore。什么是Semaphore?在前面我们讲过的synchronized和ReentrantLock都是一次只允许一个线程访问某个资源,而Semaphore(......