一、效率低
1,锁的释放情况少
当一个线程获取到对应的Synchronized这把锁并且正在执行的时候,其他线程如果也想得到这把锁只能等待,等待当前线程去释放。但是只有两种情况下锁会得到释放,一个是该段同步代码执行完毕了,还有一个是未执行完毕但是执行的过程中抛出了异常。如果我们这把锁由于要等待IO的操作或者其他操作费了很长时间,但是有没有主动地区释放锁,其他线程只能等待,这是非常影响程序执行效率的。这个时候就需要一种机制,让这种一直在等待又影响其他线程的情况得到遏制,对于Lock,它就可以办到。
2,试图获取锁时不能设定超时
只能干巴巴地等待,无法设定超时后就不做等待。相比之下,Lock可以设置超时时间。
3,不能中断一个正在试图获取锁的线程
Lock是有中断能力的。
二、不够灵活(读写锁更灵活)
1,加锁和释放的时机单一,不能自己控制加锁和解锁的时机
加锁:锁住某个对象,那么这个对象就是这把锁
释放:释放这个对象,意味着解了这把锁
2,每一个锁仅有单一的条件(某个对象),可能是不够的。
比如我们有一种读写锁,它的加锁释放锁的时机,非常灵活。它在做读操作的时候是不会加锁的,而在做写操作的时候才会加锁。这样就可以大大提高我们的效率又不会造成线程安全问题,因为读的时候不会带来风险。
所以我们是希望一个锁能够更加灵活的,让我们能够去掌控它的加锁时机和释放时机。
三、无法知道是否成功获取到锁
我们用Synchronized对代码加锁,我们没有办法提前知道它是成功了还是失败了,相比之下,Lock可以去尝试,如果成功了dosth1,如果没有成功dosth2。
Lock interface相关方法
public static void main(String[] args) throws InterruptedException {
Lock lock = new ReentrantLock();
//可以配置自己的锁,灵活地控制
lock.lock();//控制加锁的时机
lock.unlock();//控制释放的时机
lock.tryLock();//尝试获取这把锁
lock.tryLock(10,TimeUnit.SECONDS);//尝试10s内获取这把锁,如果过了时间还没获取到就放弃
}