CyclicBarrier和CountDownLatch有什么区别?Semaphore(信号量)了解吗?
  qPDHaeUaDv9Q 2023年11月02日 33 0

一、CyclicBarrier和CountDownLatch有什么区别?

两者最核心的区别:

CountDownLatch是一次性的,而CyclicBarrier则可以多次设置屏障,实现重复利用;

CountDownLatch中的各个子线程不可以等待其他线程,只能完成自己的任务;而CyclicBarrier中的各个线程可以等待其他线程

CyclicBarrier和CountDownLatch有什么区别?Semaphore(信号量)了解吗?_信号量

二、Semaphore(信号量)

Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。

听起来似乎很抽象,现在汽车多了,开车出门在外的一个老大难问题就是停车 。停车场的车位是有限的,只能允许若干车辆停泊,如果停车场还有空位,那么显示牌显示的就是绿灯和剩余的车位,车辆就可以驶入;如果停车场没位了,那么显示牌显示的就是绿灯和数字0,车辆就得等待。如果满了的停车场有车离开,那么显示牌就又变绿,显示空车位数量,等待的车辆就能进停车场。

我们把这个例子类比一下,车辆就是线程,进入停车场就是线程在执行,离开停车场就是线程执行完毕,看见红灯就表示线程被阻塞,不能执行,Semaphore的本质就是协调多个线程对共享资源的获取。

CyclicBarrier和CountDownLatch有什么区别?Semaphore(信号量)了解吗?_数据库连接_02

我们再来看一个Semaphore的用途:它可以用于做流量控制,特别是公用资源有限的应用场景,比如数据库连接。

假如有一个需求,要读取几万个文件的数据,因为都是IO密集型任务,我们可以启动几十个线程并发地读取,但是如果读到内存后,还需要存储到数据库中,而数据库的连接数只有10个,这时我们必须控制只有10个线程同时获取数据库连接保存数据,否则会报错无法获取数据库连接。这个时候,就可以使用Semaphore来做流量控制,如下:

public class SemaphoreTest {
  private static final int THREAD_COUNT = 30;
  private static ExecutorService threadPool =
  Executors.newFixedThreadPool(THREAD_COUNT);
  private static Semaphore s = new Semaphore(10);
  public static void main(String[] args) {
    for (int i = 0; i < THREAD_COUNT; i++) {
      threadPool.execute(new Runnable() {
        @Override
        public void run() {
          try {
            s.acquire();
            System.out.println("save data");
            s.release();
            } catch (InterruptedException e) {
          }
        }
      });
    }
    threadPool.shutdown();
  }
}

在代码中,虽然有30个线程在执行,但是只允许10个并发执行。Semaphore的构造方法Semaphore(int permits )接受一个整型的数字,表示可用的许可证数量。

Semaphore(10) 表示允许10个线程获取许可证,也就是最大并发数是10。Semaphore的用法也很简单,首先线程使用 Semaphore的acquire()方法获取一个许可证,使用完之后调用release()方法归还许可证。还可以用tryAcquire()方法尝试获取许可证。

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

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

暂无评论

推荐阅读
qPDHaeUaDv9Q