synchronized:任何对象都内置了一个监听器,即可以作为锁,一般是this当前类。
可以是修饰代码块,也可以是方法区
ReentrantLock:可重入锁
需要先声明,new一个ReentrantLock 对象:
ReentrantLock lock = new ReentrantLock();
通过lock.lock获取锁
通过lock.unlock释放锁
需要先声明,new一个ReentrantLock 对象:
ReentrantLock lock = new ReentrantLock();
通过lock.lock获取锁
通过lock.unlock释放锁
1、可实现公平锁和非公平锁,默认非公平锁,和synchronized一样
公平锁:解决线程间的竞争,锁饥渴
ReentrantLock lock = new ReentrantLock(true);
new的时候通过构造函数给true即可
底层:
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
2、ReentrantLock 可声明锁可中断,lock.Interruptibly()
Interruptibly:可中断的
thread.interrupt();
使用synchronized实现锁时,阻塞在锁上的线程除非获得锁否则将一直等待下去
使用ReentrantLock 可中断其中一个线程,使得锁释放
3、获取锁时限时等待
lock.trylock()//返回结果:true表示获取锁成功,false表示获取锁失败
栗子:
try {
while(!lock1.tryLock()){
TimeUnit.MILLISECONDS.sleep(10);
}
while(!lock2.tryLock()){
lock1.unlock();
TimeUnit.MILLISECONDS.sleep(10);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock1.unlock();
!lock2.tryLock().unlock();
System.out.println(Thread.currentThread().getName()+"正常结束!");
}
4、线程通信
synchronized: 使用wait,notify
wait:1、使当前线程处于等待,没有其他被唤醒则一直等待下去。2、同时释放当前锁
notify/All:唤醒处于等待状态的线程,进入就绪状态,等待获取锁
//代码块
synchronized{
条件(){
obj.wait();
}
xxx;
obj.notify();
}
ReentrantLock :
业务:入队和出队线程安全,入队满阻塞,出队空阻塞
static ReentrantLock lock = new ReentrantLock();
static Condition condition = lock.newCondition();
lock.lock();
try {
条件(..队列满了..){
condition.await();
}
condition.signal();
} finally {
lock.unlock();
}
参考:https://www.cnblogs.com/takumicx/p/9338983.html#reentrantlock%E7%AE%80%E4%BB%8B