一、显式锁Lock
特点:可轮询的、定时的以及可中断的锁获取操作、非快结构的加锁(对应于synchronized的加锁和释放都是在同一块代码块中)
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;//可中断锁(在获取锁的时候可以响应中断)
boolean tryLock(); //轮询锁
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;//定时锁
void unlock(); //释放锁
Condition newCondition();
}
使用的一般结构:
Lock lock = new ReentrantLock();
lock.lock();
try{
//处理任务
}catch(Exception ex){
//todo
}finally{
lock.unlock(); //释放锁
}
二、读写锁ReadWriteLock
特点允许多个线程同时读,允许一个线程写
public interface ReadWriteLock {
Lock readLock();
Lock writeLock();
}
ReentrantReadWriteLock(默认非公平锁)
ReentrantLock lock= new ReentrantReadWriteLock();
Lock readLock = lock.readLock();
Lock writeLock = lock.writeLock();
三、锁的公平性
公平锁---按照请求所的顺序来获取锁(等待时间)
非公平锁---(一种情况是在发出请求锁时发现锁状态可用,直接获得锁,忽略之前队列中等待的请求)
一般非公平锁的性能优于公平锁
比较适合使用公平锁的情况:持有锁的时间相对较长,或者请求锁的平均时间间隔较长
常见锁的公平性:
synchronized(内置锁,互斥锁)就是非公平锁,它无法保证等待的线程获取锁的顺序
ReentrantLock(互斥锁)默认创建的是非公平锁,可以通过参数创建公平锁
ReentrantReadWriteLock 默认创建的是非公平锁,可以通过参数创建公平锁
四、synchronized和ReentrantLock、ReentrantReadWriteLock之间的选择
优先在满足需求的情况下使用synchronized,只有在一些高级需求而synchronized满足不了的时候在使用ReentrantLock;
针对ReentrantLock和ReentrantReadWriteLock,只有在测试使用ReentrantReadWriteLock性能明显提升的时候才使用;
选择顺序总结:synchronized > ReentrantLock > ReentrantReadWriteLock
备注:线程同步:同时满足互斥性和内存可见性