1 J.U.C简介
- java.util.concurrent 简称,java并发工具包
- 线程池
- 阻塞队列
- 计时器/同步器
- 并发集合
2 Lock的基本使用
-
synchronized
不够灵活,锁的释放无法人为控制,只能等待同步代码块执行完成或发生异常 -
Lock
java.util.concurrent.locks 包下的接口,提供了锁的获得与释放的接口方法,在JUC中存在众多实现
image.png
3 ReentranLock重入锁
- 同一线程 通过
Lock.lock()
获得重入锁,当此线程再次调用时不会被阻塞可以进入,即:同一线程"一次锁定多次进入",其它线程此时调用进行阻塞 -
synchronized
也支持重入 -
ReentranLock
重入锁的设计目的是为了解决死锁
public class ThreadDemo1 {
public synchronized void func1(){//获取对象锁
System.out.println("func1");
func2();
}
public void func2(){
synchronized (this){//同一线程,同一把锁允许重入,增加重入次数,并没有死锁
System.out.println("func2");
}//同步代码执行完成,减少重入次数
}
public static void main(String[] args) {
ThreadDemo1 demo1 = new ThreadDemo1();
demo1.func1();
}
}
public class ThreadDemo2 {
//重入锁
static Lock LOCK = new ReentrantLock();
public void func1(){
LOCK.lock();//获得重如锁
//....
LOCK.unlock();//释放重入锁
}
}
4 读写锁ReentrantReadWriteLock
- 适用于读多写少的操作,例如缓存更新
- 读锁&读锁->可重入
- 读锁&写锁(写锁&读锁)->阻塞不可重入
public class ThreadDemo3 {
//读写锁
static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
//读锁
static ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
//写锁
static ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
//缓存
static Map<String,Object> cache = new HashMap<String, Object>();
/**
* Description:根据key从缓存中获取对象
* @Param [key]
* @return java.lang.Object
**/
public final Object getFromCache(String key){
readLock.lock();//获取'读锁'
try {
return cache.get(key);
} finally {
readLock.unlock();//释放'读锁'
}
}
/**
* Description:向缓存中添加对象
* @Param [key, value]
* @return void
**/
public void putToCache(String key,final Object value){
writeLock.lock();//获取'写锁'
try {
cache.put(key,value);
} finally {
writeLock.unlock();//释放'写锁'
}
}
}
5 AQS原理分析
- 同步工具
ReentrantLock 中AQS实现原理
ReentrantLock.Sync(内部类).lock()
Sync有两个子类
FairSync-公平锁(不允许插队)
NonfairSync-非公平锁(允许插队)
分别重写了lock()方法
网友评论