知识图谱
线程状态切换
锁
CAS
Compare-And-Swap,轻量级锁,读取数据时不进行加锁,在准备写回数据时,比较原子是否修改,若未被其他线程修改则写回,若已被修改,则重新执行读流程。
ABA问题,解决方法:增加额外的标志位或时间戳
Synchronized
- 对象加锁,JVM中对象在内存中分三块区域:对象头、实例数据、对其填充。对象头中保存了锁标志位和指向Monitor对象的起始地址。当monitor对某个对象持有后,就会处于锁定状态(Owner指向)。
- 方法加锁,通过ACC_SYNCHRONIZED
- 代码块,通过monitorenter和monitorexit实现
AQS & Lock
当获得锁的线程需要等待某个条件时,会进入condition的等待队列,等待队列可以有多个。当condition条件满足时,线程从等待队列进入同步队列获取锁的竞争。
ReenterLock内部有公平锁和非公平锁,区别在与新来的线程是否比已经在同步队列中的等待线程更早获得锁。
Seamphore也是基于AQS,区别在于Semaphore是共享锁,ReentrantLock是独占锁。
线程池
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
- corePoolSize:核心线程数
- maximumPoolSize:最大线程数
- keepAliveTime/unit:线程空闲时间和时间单位
- workQueue:ArrayBLockingQueue(有界队列),LinkedBlockingQueue(无界队列),SynchronusQueue(同步队列,内部没有缓冲区)
- threadFactory:对线程的一些属性如group、线程名、优先级等设置。一般用默认工厂方式
- 线程池满时的拒绝方式:Abort会直接抛出RejectExecutionException;Discard策略将任务直接丢弃;callerRuns:由提交任务的线程执行提交的任务;DiscardOldest:丢弃最早的任务
JUC常用工具
分布式锁
当在分布式模型下,数据只有一份(或有限制),需要利用锁的技术控制某一时刻修改数据的进程数。分布式锁将标记存在于公共内存,如Redis。
分布式事务
分布式事务指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于分布式系统的不同节点之上。分布式事务要保证各个节点之上的任务要么全部成功,要么全部失败。