JavaTutorial10
CAS
Atomic原子类
CountDownLatch
await方法的意义是阻塞当前线程,直到之前创立的所有线程都完成了任务对吧。那为什么还是会出现图二的情况呢?根据提供的两张图片,完整的代码如下:
图一代码(Main类):
1 | public class Main { |
图二代码(CountDownLatch示例):
1 | CountDownLatch cd = new CountDownLatch(2); |
关于CountDownLatch.await()方法和图二的情况:
CountDownLatch.await()确实是阻塞当前线程,直到计数器归零。但出现图二情况(先输出”倒计时6”、”倒计时5”,然后是”主线程”,接着是”倒计时4”等)的原因是:
- 计数器的初始值:图二中的CountDownLatch初始值是2,不是7。这意味着Thread A在执行了两次countDown()后(输出”倒计时6”和”倒计时5”后),计数器就已经归零。
- 线程调度的不确定性:当计数器归零时,主线程被唤醒并继续执行,输出”主线程”。但这并不意味着Thread A会立即停止 - 它会继续执行剩余的循环迭代,输出”倒计时4”直到”倒计时0”。
- 线程执行顺序:操作系统的线程调度器决定了哪个线程在特定时刻获得CPU时间片。即使主线程被唤醒,Thread A可能仍然继续执行一段时间后,主线程才真正获得执行机会。
简而言之,CountDownLatch保证了主线程会等待直到计数器归零,但并不保证其他线程会在此时停止执行。两个线程(主线程和Thread A)在计数器归零后都可以继续执行,它们的具体执行顺序取决于线程调度器。
这就是为什么你会看到”倒计时6”、”倒计时5”、”主线程”、”倒计时4”等这样的输出顺序 - 计数器在第二次countDown()后归零,但Thread A继续完成了它的所有循环迭代。
CyclicBarrier
Semaphore
线程池原理
Executor框架
ThreadPoolExecutor
FutureTask
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 0kr's Blog!
评论