java 多线程知识梳理2
ReentrantLock和synchronized的选择
1 synchronized的弊端,简化了代码工作,并且与异常处理操作实现了很好的交互,但是表现不够灵活,对线程控制较小,比如无法中断等待的线程,或者无法在请求获取锁时无限的等待,也没法实现非阻塞结构的加锁规则。
2 reentrantlock, java5.0以后才引入,实现了Lock 接口,提供了与synchronized相同的互斥性和内存可见性。在java5.0里面性能优势比内置锁明显,java6.0里面差不多,是内置锁的补充,不是替代,
public interfance Lock{
void lock();
void lockInterruptibly() throws InterruptedException;//可中断的所获取操作
boolean tryLock();//轮询锁,避免死锁的发生
boolean tryLock(Long timeout, TimeUnit unit);//定时锁,避免死锁的发生
void unlock();
Condition newCondition();
}
使用标准
Lock lock = new reentrantLock()
......
lock.lock();
try{
}catch(){
//执行更新操作
}finally{
lock.unlock();
}
tryLock,比如同时需要获取两个对象的锁才能开始执行业务,
if(alock.tryLock())
try{
if(block.tryLock())
try{
//执行业务操作
}catch{
}finally{
block.unlock();
}
}catch{
}finally{
alock.unlock();
}
3 reentrantReadWriteLock 读写锁,一个资源可以被多个读操作访问,或者被一个写操作访问,但两者不能同时进行。他允许多个执行读操作的线程访问数据结构,能有效提高程序性能。
pubilc interface ReadWriteLock(){
Lock readLock();
Lock writeLovk();}
基于读写锁包装map:
public class ReadWriteMap{
private final Map<K,V> map;
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock r = lock.readLock();
private final Lock w = lock.writeLock();
public ReadWriteMap(Map<K,V> map){
this.map=map;
}
public V put(K key,V value){
w.lock();
try{
return map.put(key,value);
}catch{
}finally{
w.unlock();
}
public V get(K key){
r.lock();
try{
return get(key)
}catch{
}finally{
r.unlock();
}
}