【面试实战】# 并发编程
1.线程状态请表明 Java 中线程的几种状态,并描述每种状态的特点和转换条件。
[*]NEW(新建):线程被创建,但尚未启动。
[*]RUNNABLE(可运行):线程正在运行,可能在执行代码,也可能等候操作体系资源。
[*]BLOCKED(阻塞):线程在等候监视器锁,以便进入同步块/方法。
[*]WAITING(等候):线程等候另一个线程显式地唤醒它(例如,Object.wait(),Thread.join())。
[*]TIMED_WAITING(计时等候):线程等候另一个线程在指定的时间内唤醒它(例如,Thread.sleep(),Object.wait(long timeout))。
[*]TERMINATED(终止):线程已完成执行。
线程状态的转换条件包罗线程的启动、资源竞争、同步块/方法的进入与退出、以及超时等。
2.synchronized 和 ReentrantLock
synchronized 和 ReentrantLock 有什么区别?在什么情况下会选择使用 ReentrantLock?
[*]synchronized:是Java中的内置同步机制,修饰方法或代码块,使用对象内部的监视器锁。简单易用,但功能有限(如不能尝试锁定、不能定时锁定)。
[*]ReentrantLock:是 java.util.concurrent.locks 包中的锁,具有更多的高级功能,如可重入、可定时、可中断的锁定方式,支持公平锁和非公平锁。
选择 ReentrantLock 的情况:
[*]需要尝试锁定或定时锁定。
[*]需要公平锁定(顺序锁定)。
[*]需要更灵活的锁定机制和条件变量(例如 Condition)。
3.线程池
请说明 ThreadPoolExecutor 类的核心参数及其作用。你会如何调整线程池的配置来应对高并发的需求?
ThreadPoolExecutor 类的核心参数:
[*]corePoolSize:核心线程数,线程池中始终保持存活的线程数。
[*]maximumPoolSize:最大线程数,线程池中允许的最大线程数。
[*]keepAliveTime:线程空闲时间,当线程数超过 corePoolSize 时,超时未任务的线程会被终止。
[*]unit:keepAliveTime 的时间单位。
[*]workQueue:任务队列,保存等候执行的任务。
[*]threadFactory:线程工厂,创建新线程的方式。
[*]handler:拒绝策略,当任务无法提交到线程池时的处置惩罚方式。
高并发配置发起:
[*]根据任务类型调整 corePoolSize 和 maximumPoolSize。
[*]选择合适的队列(有界/无界)避免资源耗尽。
[*]使用合适的拒绝策略(如 CallerRunsPolicy)以防止任务丢失。
4.Future 和 CompletableFuture
Future 和 CompletableFuture 有何区别?在什么情况下你会选择使用 CompletableFuture?
[*]Future:体现一个异步计算的结果,可以通过 get() 方法获取计算结果,但会阻塞直到任务完成。适用于简单的异步任务。
[*]CompletableFuture:扩展了 Future,提供了更丰富的 API 来进行异步任务的组合和处置惩罚(如 thenApply、thenAccept)。支持链式调用和异常处置惩罚。
使用 CompletableFuture 的情况:
[*]需要进行多个异步任务的组合。
[*]需要非阻塞地处置惩罚异步结果。
[*]需要处置惩罚异步计算的异常。
5.阻塞队列
请介绍几种常用的阻塞队列及其适用场景。
常用的阻塞队列:
[*]ArrayBlockingQueue:基于数组的有界阻塞队列。
[*]LinkedBlockingQueue:基于链表的有界或无界阻塞队列。
[*]PriorityBlockingQueue:支持优先级排序的无界阻塞队列。
[*]DelayQueue:支持延时获取元素的无界阻塞队列。
[*]SynchronousQueue:不存储元素的队列,每个插入操作必须等候对应的移除操作。
适用场景:
[*]ArrayBlockingQueue:固定容量的场景,避免队列过大。
[*]LinkedBlockingQueue:需要动态增长的队列长度场景。
[*]PriorityBlockingQueue:需要优先级处置惩罚的场景。
[*]DelayQueue:需要延迟执行的任务调理场景。
[*]SynchronousQueue:生产者和消费者一对一交互的场景。
6.CAS
什么是 CAS(Compare-And-Swap)?它是如安在 Java 中实现的?请描述其优缺点。
CAS(Compare-And-Swap):
[*]CAS 是一种无锁算法,用于实现原子操作。通过比较内存中的某个值与预期值,假如相同则修改成新值,否则不修改。
[*]在 Java 中,CAS 通过 sun.misc.Unsafe 类中的方法实现(如 compareAndSwapInt)。
优点:
[*]高效,无需阻塞线程。
[*]适合在多线程环境下包管数据一致性。
缺点:
[*]可能会导致忙等候(假如 CAS 操作频繁失败)。
[*]不适合复杂的同步场景(如需要维护多个变量的一致性)。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]