synchronized和java.util.concurrent.locks.Lock

synchronized

Java关键字

同步代码块、同步方法、静态同步方法

一个代码块或者一个方法被synchronized关键字修饰之后,如果一个线程获得了当前对象的monitor之后,就执行该代码块或方法,其它线程一直等待(阻塞)

获得对象锁的线程何时释放锁?

(1)同步代码块或者同步方法执行完毕

(2)线程在执行过程中发生异常

问题:如果获取到对象锁的线程由于某些原因阻塞了,又不会释放锁,就会使得等待该对象锁的其他线程一直阻塞

synchronized不需要用户手动释放锁

无法判断锁的状态(无法判断线程获取锁是否成功)

无法中断一个正在等待锁的线程

Lock

java.util.concurrent.locks.Lock

synchronized和java.util.concurrent.locks.Lock

(1)lock

获取锁,如果锁被其它线程占用,则等待

(2)unlock

必须手动释放锁,finally块中,即使发生异常也不会主动释放锁

(3)空参的tryLock

尝试获取锁

如果获取成功,true;如果锁被其它线程占用,false,不会等待,立即返回。

(4)带参的tryLock

尝试获取锁

如果发现锁被其它线程占用,则等待指定的时间

在等待的时间之内获取到了锁,true;否则,在等待时间到了之后,返回false

(5)lockInterruptibly

InterruptedException

当两个线程同时通过该方法获取锁时,如果一个线程获得了锁,另一个线程只能等待,那么,对另一个线程可以调用interrupt方法中断线程的等待状态

 


 

 

对比

1.synchronized------Java关键字(内置的Java语言实现)

 Lock------java.util.concurrent.locks包下的接口

2.释放锁

  synchronized会在代码块或者方法执行完毕之后,或者在代码块或方法中发生异常时,自动释放锁

  Lock不会主动释放锁(即使异常也不主动释放),必须在finally代码块中调用unlock手动释放锁

3.等待锁的线程的中断

  synchronized等待锁的线程无法终端,会一直等待,程序负担重

  Lock调用lockInterruptibly获得锁时,支持中断一个正在等待锁的线程

4.获得锁的状态(是否成功获得锁)

  synchronized无法获得

  Lock调用tryLock方法获得锁时,可以根据返回值得知当前线程是否成功获得锁

 

资源竞争激烈时,Lock性能高

都具备可重用性