你知道多少种并发编程常⻅的锁

ReentrantLock是公平锁还是⾮公平锁,为什么这样设计
在Java中,ReentrantLock
既可以是公平锁,也可以是非公平锁,这取决于我们在构造时的选择。
当我们创建ReentrantLock
对象时,可以选择传入一个布尔参数:
-
如果传入的是 true
,那么创建的ReentrantLock
就是公平锁。 -
如果传入的是 false
或者没有传入参数(因为默认是false
),那么创建的ReentrantLock
就是非公平锁。
这样设计的原因是因为公平锁和非公平锁各自有不同的优缺点及适用场景:
-
公平锁(Fair)保证了各个线程获取锁的公平性,线程获取锁的顺序是按照线程加锁的顺序来分配的,也就是先来先得的FIFO先进先出顺序。因为要维护一个有序队列,所以公平锁的实现成本和操作成本都比较高,性能较低。
-
非公平锁(Unfair)则是一种获取锁的抢占机制,是随机获取锁,和线程申请锁的顺序无关,因此可能产生“线程饥饿”的问题。但是在高并发、高负载的情况下,非公平锁的性能远高于公平锁。
因此,根据不同的应用场景,我们可以选择不同的锁策略,这就是为什么ReentrantLock
设计成可以选择是公平锁还是非公平锁的原因。
介绍下ThreadLocal,⼀般什么场景下会使⽤

说下Thread/ThreadLocal/ThreadLocalMap 三者的关系
-
关系 -
Thread类,⾥⾯有⼀个ThreadLocalMap类型的变量,变量名字叫threadLocals,但是 ThreadLocalMap类型
-
ThreadLocal类,⾥⾯有⼀个ThreadLocalMap静态内部类 提供⼀系列⽅法操作ThreadLocalMap,⽐如get/set/remove
-
隔离Thread和ThreadLocalMap,防⽌直接创建ThreadLocalMap
-
⾃身的get/set内部会判断当前线程是否已经绑定⼀个ThreadLocalMap,有就继续使⽤,没有 就为其⾃身绑定
-
ThreadLocalMap 就是保存ThreadLocal的map结构,key就是ThreadLocal本身 -
所以⼀个线程只能存储⼀个值,可以理解为JVM内部维护的⼀个Map<Thread, Object> -
当线程需要⽤到Object,就⽤【当前线程】去Map⾥⾯获取对应的Object -
操作 -
Thread类⾥⾯有⼀个ThreadLocalMap类型的变量,不能直接操作这个ThreadLocalMap -
需要通过【⼯具箱】ThreadLocal才可以操作ThreadLocalMap -
⼀个Thread只能有⼀个ThreadLocalMap ThreadLocalMap以ThreadLocal为键存储数据 -
总结 -
ThreadLocal本身并不存储值 ( 是⼀个壳⼦ ), 它只是⾃⼰作为⼀个key来让线程从 ThreadLocalMap获取value。 -
因为这个原理,所以ThreadLocal能够实现 “每个线程之间的数据隔离”,获取当前线程的局部变量 值,不受其他线程影响
JVM⾥⾯的四⼤引⽤是哪些?使⽤场景有哪些

ThreadLocal为啥需要设计成弱引⽤,⽤完需要remove呢?
说下CompletableFuture的⽤途和使⽤场景
-
核⼼⽤途: -
在项⽬开发中,由于业务规划逻辑的原因,业务需要从多个不同的地⽅获取数据, -
然后汇总处理为最终的结果,再返回给请求的调⽤⽅,就是聚合信息处理类的处理逻辑 -
如果常⽤串⾏请求,则接⼝响应时间⻓;利⽤CompletableFuture则可以⼤⼤提升性能 -
针对多任务,需要进⾏任务编排调度,也可以使⽤CompletableFuture进⾏完成 -
CompletableFuture类实现了Future和CompletionStage接⼝,相当于⼀个Task编排⼯具 -
xxxx():表示该⽅法将继续在当前执⾏CompletableFuture的⽅法线程中执⾏ -
xxxxAsync():表示异步,在线程池中执⾏ -
在没有指定线程池的情况下,使⽤的是CompletableFuture内部的线程池 ForkJoinPool ,线 程数默认是 CPU 的核⼼数 -
⼀般不要所有业务共⽤⼀个线程池,避免有任务执⾏⼀些很慢的 I/O 操作, -
会导致线程池中所有线程都阻塞在 I/O 操作上,从⽽造成线程饥饿,影响整个系统的性 能 -
是Java8新增接⼝,⽤于异步执⾏中的阶段处理,CompletableFuture是其中的⼀个实现类 -
对任务处理可以构造⼀条结果传递链,在结果传递过程中任何⼀个CompletionStage都可以对 结果进⾏处理 -
⼏个CompletionStage可以串联起来,⼀个完成的阶段可以触发下⼀阶段的执⾏ -
包括异常处理、类型转换,可以构造⾮常简单的传递链也可以构造很复杂的传递链 -
表示异步计算的结果,它提供了检查计算是否完成的⽅法,以等待计算的完成 -
计算完成后只能使⽤ get ⽅法来获取结果,有cancel、get、isDone、isCancelled等⽅法 -
Future -
CompletionStage -
当前的Task到底由那个Thread执⾏,使⽤的不好可能会有性能问题, 根据 CompletableFuture的 ⽅法命名可以掌握
说下什么是池化思想,有哪些应⽤场景ikkgpt.com 人工智能助手让面试变得更简单!!
说下ThreadPoolExecutor设计原理和核⼼参数
说下java⾃带的Executors线程池种类和特点
⽣产环境事故分析-线程池使⽤选择问题

原文始发于微信公众号(编译):Java金三银四面试-JUC基础
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/227170.html