目录
三、ReentrantLock是如何实现锁公平和非公平性的?
八、ConcurrentHashMap的size()方法是线程安全的吗?为什么?
九、wait和sleep是否会触发锁的释放以及CPU资源的释放?
十、DCL单例模式设计为什么需要volatile修饰实例对象
一、什么是守护线程,它有什么特点
守护线程,它是一种专门为用户线程提供服务的线程,它的生命周期依赖于用户线程。
只有JVM中仍然还存在用户线程正在运行的情况下,守护线程才会有存在的意义。
否则,一旦JVM进程结束,那守护线程也会随之结束。
也就是说,守护线程不会阻止JVM的退出。但是用户线程会!
守护线程和用户线程的创建方式是完全相同的,我们只需要调用用户线程里面的setDaemon方法并且设置成true,就表示这个线程是守护线程。
因为守护线程拥有自己结束自己生命的特性,所以它适合用在一些后台的通用服务场景里面。比如JVM里面的垃圾回收线程,就是典型的使用场景。
这个场景的特殊之处在于,当JVM进程技术的时候,内存回收线程存在的意义也就不存在了。
所以不能因为正在进行垃圾回收导致JVM进程无法技术的问题。
但是守护线程不能用在线程池或者一些IO任务的场景里面,因为一旦JVM退出之后,守护线程也会直接退出。
就会可能导致任务没有执行完或者资源没有正确释放的问题。
二、请谈谈AQS是怎么回事儿
这个问题从几个方面来回答:
AQS它是J.U.C这个包里面非常核心的一个抽象类,它为多线程访问共享资源提供了一个队列同步器。
在J.U.C这个包里面,很多组件都依赖AQS实现线程的同步和唤醒,比如Lock、Semaphore、CountDownLatch等等。
(如图),AQS内部由两个核心部分组成:
1、一个volatile修饰的state变量,作为一个竞态条件
2、用双向链表结构维护的FIFO线程等待队列
它的具体工作原理是,多个线程通过对这个state共享变量进行修改来实现竞态条件,竞争失败的线程加入到FIFO队列并且阻塞,抢占到竞态资源的线程释放之后,后续的线程按照FIFO顺序实现有序唤醒。

AQS里面提供了两种资源共享方式,一种是独占资源,同一个时刻只能有一个线程获得竞态资源。比如ReentrantLock就是使用这种方式实现排他锁。
另一种是共享资源,同一个时刻,多个线程可以同时获得竞态资源。CountDownLatch或者Semaphore就是使用共享资源的方式,实现同时唤醒多个线程。
三、ReentrantLock是如何实现锁公平和非公平性的?
先解释一下个公平和非公平的概念:
公平:指的是竞争锁资源的线程,严格按照请求顺序来分配锁。
非公平:表示竞争锁资源的线程,允许插队来抢占锁资源。
ReentrantLock默认采用了非公平锁的策略来实现锁的竞争逻辑。
(如图)其次,ReentrantLock内部使用了AQS来实现锁资源的竞争,没有竞争到锁资源的线程,会加入到AQS的同步队列里面,这个队列是一个FIFO的双向链表。

在这样的一个背景下,公平锁的实现方式就是,线程在竞争锁资源的时候判断AQS同步队列里面有没有等待的线程。

本文探讨了守护线程的特性、AQS的原理和使用、ReentrantLock的公平与非公平锁、CompletableFuture的异步回调、线程状态区别、Thread和Runnable的差异、AQS选择双向链表的原因、ConcurrentHashMap的size方法、wait/sleep行为以及DCL单例模式中的volatile修饰。
3万+

被折叠的 条评论
为什么被折叠?



