Synchronized与Lock区别

Java里面的两种管程模型

之前我们了解了Java里面的一种管程模型monitor,synchronized就是基于Monitor实现的管程模型,在这个模型里面,synchronized中用锁解决了资源互斥问题,然后提供了wait(),notify(),notifyAll() 一组方法解决了线程同步问题,Java里面另一种管程模型就是Lock+Condition, 在此模型中 Lock是用来解决资源互斥的问题,而Condition里也提供wait(),signal(),signalAll() 同样也是解决线程同步问题,如果你理解了synchronized那么我相信你再来看Lock+Condition也会很简单。

 

我们用两种管程模型一对比会发现,他们的逻辑基本没什么区别,同样都是所用锁解决互斥问题,提供了一个阻塞队列,并同时提供了一组方法来对阻塞队列的线程进行操作,达到解决线程同步的效果。也许你会想既然有了synchronized为什么jdk还要提供Lock和Condition呢,而且synchronized傻瓜式的应用更方便简单,而Lock和Condition却麻烦多了,要自己加锁、释放锁,一不小心就出BUG了。

 

Synchronized和Lock的区别

当然,既然存在就有其合理性,也许你会想到Lock的性能要比synchronized好,在JDK1.6版本之前Lock的性能的确要比synchronized要好,但是在JDK1.6值周 synchronized做了一系列的优化后,synchronized的整体性能提升上来了,所以性能并非Lock存在的原因,那么究竟是什么原因让JDK非得重复造轮子,答案就是Lock提供了更多解决死锁问题的方法:

 

1、Lock提供了超时机制

超时机制可以让我们更灵活的控制程序,而不必陷入等待锁的死循环中,在一定时间内获取不到锁,线程就释放出来继续干下面的事情,而synchronized一旦尝试加锁,就会死等,所以这种情况就有可能会出现死锁。

 

2、Lock阻塞的线程可以响应中断

synchronized线程一旦获取锁失败就会进行阻塞,而阻塞状态下的线程是无法响应中断(Interrupted)的,而Lock是支持中断响应的,一旦发现可能出现死锁,可立即中断某个线程。

 

3、Lock支持非阻塞的获取锁

Lock支持不阻塞的方式获取锁,以这种方式获取锁时会返回获取锁是否成功,当尝试获取锁不成功时,线程并不会阻塞。

 

4、Lock+Condition可以支持多个条件

synchronized只有一个等待队列,任何情况的阻塞都是放在一个队列里面的,Lock可以创建多个Condition队列,不同的Condition控制不同的条件,每个Condition有单独的一个队列。

来源:知乎

你可能感兴趣的:(Lock,Synchronized,java)