以下都是Java的基础面试题,相信大家都会有种及眼熟又陌生的感觉、看过可能在短暂的面试后又马上忘记了。JavaPub在这里整理这些容易忘记的重点知识及解答,建议收藏,经常温习查阅
。
概念:
CountDownLatch 是一个同步的辅助类,允许一个或多个线程,等待其他一组线程完成操作,再继续执行。简单来说:CountDownLatch 是一个计数器,可以保证线程之间的顺序执行把线程从并发状态调整为串行状态保证了线程的执行顺序。(只可以使用一次)
CyclicBarrier 是一个同步的辅助类,允许一组线程相互之间等待,达到一个共同点,再继续执行。典型场景:可以用于多线程计算数据,最后合并计算结果。(可以多次使用)
分享一个直观的代码:
package com.javapub.test; import java.util.concurrent.CountDownLatch; /** * @Author: JavaPub * @License: https://github.com/Rodert/ * @Contact: https://javapub.blog.csdn.net/ * @Date: 2022/1/1 16:50 * @Version: 1.0 * @Description: countDownLatch 可以保证线程之间的顺序执行把线程从并发状态调整为串行状态保证了线程的执行顺序。 * demo效果:当打印完B,再打印C。 */ class ThreadA extends Thread { private CountDownLatch down; public ThreadA(CountDownLatch down) { this.down = down; } @Override public void run() { System.out.println("A"); try { down.await();//相当于wait(),调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("C"); } } class ThreadB extends Thread { private CountDownLatch down; public ThreadB(CountDownLatch down) { this.down = down; } @Override public void run() { System.out.println("B"); System.out.println(down.getCount()); down.countDown();//将count值减1 } } public class Test { public static void main(String[] args) { CountDownLatch down = new CountDownLatch(1);//创建1个计数器 new ThreadA(down).start(); new ThreadB(down).start(); } } /*输出 A B C */
package com.roundyuan.fanggateway.test; import java.util.concurrent.CyclicBarrier; /** * @Author: JavaPub * @License: https://github.com/Rodert/ * @Contact: https://javapub.blog.csdn.net/ * @Date: 2022/1/2 13:42 * @Version: 1.0 * @Description: CyclicBarrier */ public class CyclicBarrierDemo { static class TaskThread extends Thread { CyclicBarrier barrier; public TaskThread(CyclicBarrier barrier) { this.barrier = barrier; } @Override public void run() { try { Thread.sleep(1000); System.out.println(getName() + " 到达栅栏 A"); barrier.await(); System.out.println(getName() + " 冲破栅栏 A"); Thread.sleep(2000); System.out.println(getName() + " 到达栅栏 B"); barrier.await(); System.out.println(getName() + " 冲破栅栏 B"); } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { int threadNum = 5; CyclicBarrier barrier = new CyclicBarrier(threadNum, new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " 完成最后任务"); } }); for (int i = 0; i < threadNum; i++) { new TaskThread(barrier).start(); } } } /* Thread-3 到达栅栏 A Thread-1 到达栅栏 A Thread-4 到达栅栏 A Thread-2 到达栅栏 A Thread-0 到达栅栏 A Thread-2 完成最后任务 Thread-2 冲破栅栏 A Thread-0 冲破栅栏 A Thread-4 冲破栅栏 A Thread-3 冲破栅栏 A Thread-1 冲破栅栏 A Thread-4 到达栅栏 B Thread-0 到达栅栏 B Thread-2 到达栅栏 B Thread-1 到达栅栏 B Thread-3 到达栅栏 B Thread-3 完成最后任务 Thread-3 冲破栅栏 B Thread-0 冲破栅栏 B Thread-4 冲破栅栏 B Thread-1 冲破栅栏 B Thread-2 冲破栅栏 B */
网上看到一个比较形象一个例子:
CountDownLatch: 宿管阿姨,晚上关宿舍大门睡觉,需要等到所有学生回寝,才能关门睡觉,学生之间不用相互等待,回寝就能睡觉。 (学生就是各个线程,宿管阿姨就是监听CountDownLatch为0后要执行的。) CyclicBarrier: 家庭聚餐,等待家庭成员到齐才能开饭,家庭成员之间需要相互等待,直到最后一个到达,才能同时开饭。
https://javapub.blog.csdn.net/article/details/122011870
手机随时看:微信搜【JavaPub】 JavaPub
查看更多面试题及答案