java线程/方法超时控制(2)-从CountDownLatch await细节开始

本文主要探讨Java中CountDownLatch的线程超时控制,尤其是其await方法的细节。通过两个实例,展示了如何利用await进行超时设置,并分析了await方法在遇到InterruptedException时的处理方式。同时提到了Uninterruptibles.awaitUninterruptibly方法,该方法能够避免中断异常,通过循环尝试直至超时。文章还提及CountDownLatch与线程池结合使用的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    纯记录,记忆越来越差,能力又一般,纯讨论简单细节。线程超时控制的方法有很多也有很多新的方法,CountDownLatch只是其中一种且不新,与CyclicBarrier不同的是 CountDownLatch一次性的,下面CountDownLatch的细节开始记录讨论一些东西。

    看个例子,例子1很简单,起个线程,用CountDownLatch的带超时的 await方法控制超时

例子1:

CountDownLatch countDownLatch = new CountDownLatch(1);
TestThread testThread = new TitleThread(args, countDownLatch);
testThread.start();
try {
    countDownLatch.await(countDownLatch, timeOut, TimeUnit.MILLISECONDS);
}catch (InterruptedException e) {
    // 抓到一个中断异常
} catch (Exception e) {
    // 抓到一个异常
}

await方法源码写的清楚,会抛出中断异常 InterruptedException,InterruptedException其实比较讨厌,在某些场景需要特别的留心和处理,好在这个例子里这么写显示调用线程不关心中断异常,笼统的捕获 Exception也没关系。此处不回抛出超时异常。

下面,换个写法

例子2:

import com.google.common.util.concurrent.Uninterruptibles

CountDownLatch countDownLatch = new CountDownLatch(1);
TestThread testThread = new TitleThread(args, countDownLatch);
testThread.start();
if (!Uninterruptibles.awaitUninterruptibly(countDownLatch, timeOut,TimeUnit.MILLISECONDS)){
    // 超时啦,打个日志?做个处理?随你
}

  看下 Uninterruptibles.awaitUninterruptibly 这个方法,看名字就是不许中断的等待方法,具体逻辑看源码

  /**
   * Invokes
   * {@code latch.}{@link CountDownLatch#await(long, TimeUnit)
   * await(timeout, unit)} uninterruptibly.
   */
  @GwtIncompatible("concurrency")
  public static boolean awaitUninterruptibly(CountDownLatch latch,
      long timeout, TimeUnit unit) {
    boolean interrupted = false;
    try {
      long remainingNanos = unit.toNanos(timeout);
      long end = System.nanoTime() + remainingNanos;
      while (true) {
        try {
          // CountDownLatch treats negative timeouts just like zero.
          return latch.await(remainingNanos, NANOSECONDS);
        } catch (InterruptedException e) {
          interrupted = true;
          remainingNanos = end - System.nanoTime();
        }
      }
    } finally {
      if (interrupted) {
        Thread.currentThread().interrupt();
      }
    }
  }

内部还是调用await,多了一些包装,while里不断的尝试调用await,遇到中断了?不理,剩余时间改小,继续while循环,直到超时返回。当然最后在finally里重置了中断标志位,方便上层根据中断状态做点啥

CountDownLatch配合线程池使用也不错

executorService.submit(new TestTask(xx,xx,countDownLatch));
executorService.submit(new TestTask(xx,xx,countDownLatch));
executorService.submit(new TestTask(xx,xx,countDownLatch));
executorService.submit(new TestTask(xx,xx,countDownLatch));
// 阻塞住
if (!Uninterruptibles.awaitUninterruptibly(countDownLatch, timeOut, TimeUnit.MILLISECONDS)) {
   // 超时啦,打个日志?做个处理?
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值