总结
我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。
面试题多多少少对于你接下来所要做的事肯定有点帮助,但我更希望你能透过面试题去总结自己的不足,以提高自己核心技术竞争力。每一次面试经历都是对你技术的扫盲,面试后的复盘总结效果是极好的!
CountDownLatch countDownLatch=new CountDownLatch(count);
复制代码
构造器中传入的count
为int
类型,这个计数器的初始值就是需要等待的线程数量。这个值只能被设置一次,并且CountDownLatch
不提供任何方法去修改或重置这个值。
countDown
方法:
countDownLatch.countDown();
复制代码
每当一个线程完成了自己的任务后,调用该方法,计数器的值减1。当计数器的值为0时,表示所有线程都已经完成了任务,然后在锁上等待的线程就可以恢复执行任务。
await
方法:
countDownLatch.await();
复制代码
一般主线程在启动其他线程后调用该方法,这样主线程的操作就会在这个方法上阻塞,直到其他线程完成各自的任务。一般而言,与CountDownLatch
的第一次交互就是在这里,主线程等待其他线程。
下面以一个例子来看一下具体的使用:假设我们通过第三方机构查询机票,第三方会分别去统计各个航空公司的现存票数,查询全部完成后再返回结果。主线程:
public class CountDownDemo {
private static List company= Arrays.asList(“山航”,“东航”,“青航”);
private static List flightList=new ArrayList<>();
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch=new CountDownLatch(company.size());
for (int i = 0; i < company.size(); i++) {
String name=company.get(i);
QueryThread queryThread=new QueryThread(countDownLatch,flightList,name);
new Thread(queryThread).start();
}
countDownLatch.await();
System.out.println(“=查询结束=”);
flightList.forEach(System.out::println);
}
}
复制代码
查询线程:
public class QueryThread implements Runnable{
private CountDownLatch countDownLatch;
private List fightList=new ArrayList<>();
private String name;
public QueryThread(CountDownLatch countDownLatch,List fightList, String name) {
this.countDownLatch = countDownLatch;
this.fightList=fightList;
this.name = name;
}
@Override
public void run() {
int val=new Random().nextInt(10);
try {
System.out.printf(“%s开始查询!\n”,name);
TimeUnit.SECONDS.sleep(val);
fightList.add(name+“票数:”+val);
System.out.printf(“%s查询成功!\n”,name);
countDownLatch.countDown();
}catch (Exception e){
e.printStackTrace();
}
}
}
复制代码
执行代码:
从执行结果可以看出,在3个查询线程均完成查询后,唤醒主线程,返回了最终数据。
通过这个例子,我们可以得出,如果一个接口依赖了多个第三方服务或外部接口,那么如果串行调用的话执行时间必然很长,这时候就可以使用CountDownLatch
进行并行调用,这一点的思路也比较像使用消息队列对上下游系统进行解耦的过程。
CyclicBarrier
CyclicBarrier
可以被翻译为“循环栅栏”,通过它可以实现让一组线程等待至某个状态之后再同步执行。“循环”这一点体现在当所有的等待线程都被释放后,CyclicBarrier
可以被重用。
执行的基本原理是,当线程调用了CyclicBarrier
的await()
方法后,就会处于一个barrier
的状态,也就是遇到了一个屏障。如果所有线程都执行到这个状态,那么这个屏障就会打开,使所有线程继续向下执行。
先看一下常用的几个重要方法,首先看构造方法:
总结
面试建议是,一定要自信,敢于表达,面试的时候我们对知识的掌握有时候很难面面俱到,把自己的思路说出来,而不是直接告诉面试官自己不懂,这也是可以加分的。
以上就是蚂蚁技术四面和HR面试题目,以下最新总结的最全,范围包含最全MySQL、Spring、Redis、JVM等最全面试题和答案,仅用于参考
[外链图片转存中…(img-S3ZMwrcS-1714916891467)]