countDownLatch和Semaphore用于多线程

时间:2020-03-26
本文章向大家介绍countDownLatch和Semaphore用于多线程,主要包括countDownLatch和Semaphore用于多线程使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

countDownLatch:

1.概念(jdk1.5以后引入的新概念,使用计数器模式)

  • countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
  • 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

2.源码

  • countDownLatch类中只提供了一个构造器:
  //参数count为计数值
  public CountDownLatch(int count) {  };  
  • 类中有三个方法是最重要的:
  //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
  public void await() throws InterruptedException { };   
  //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
  public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  
  //将count值减1
  public void countDown() { };  
3.实战:

  private CountDownLatch countDownLatch = new CountDownLatch(1);

  public void first(Runnable printFirst) throws InterruptedException {
    // printFirst.run() outputs "first". Do not change or remove this line.
    printFirst.run();
    countDownLatch.countDown();
  }

  public void second(Runnable printSecond) throws InterruptedException {
    countDownLatch.await();
    // printSecond.run() outputs "second". Do not change or remove this line.
    printSecond.run();
  }

4.CountDownLatch和CyclicBarrier区别:
  1.countDownLatch是一个计数器,线程完成一个记录一个,计数器递减,只能只用一次
  2.CyclicBarrier的计数器更像一个阀门,需要所有线程都到达,然后继续执行,计数器递增,提供reset功能,可以多次使用

Semaphore
1.概念

  Semaphore叫信号量,Semaphore有两个目的,第一个是多个共享资源互斥使用,第二个是并发线程数的控制。、

2.Semaphore主要方法:

  Semaphore(int permits):构造方法,创建具有给定许可数的计数信号量并设置为非公平信号量。

  Semaphore(int permits,boolean fair):构造方法,当fair等于true时,创建具有给定许可数的计数信号量并设置为公平信号量。

  void acquire():从此信号量获取一个许可前线程将一直阻塞。相当于一辆车占了一个车位。

  void acquire(int n):从此信号量获取给定数目许可,在提供这些许可前一直将线程阻塞。比如n=2,就相当于一辆车占了两个车位。

  void release():释放一个许可,将其返回给信号量。就如同车开走返回一个车位。

  void release(int n):释放n个许可。

  int availablePermits():当前可用的许可数。
3.代码实战: 

  private Semaphore semaphore = new Semaphore(0);

  public void first(Runnable printFirst) throws InterruptedException {
    // printFirst.run() outputs "first". Do not change or remove this line.
    printFirst.run();
    semaphore.release();
  }

  public void second(Runnable printSecond) throws InterruptedException {
    // printSecond.run() outputs "second". Do not change or remove this line.
    semaphore.acquire();
    printSecond.run();
  }

$flag 上一页 下一页