Java 多线程 synchronized与Lock的区别

总结

类别synchronizedLock
存在层次 Java的关键字,在jvm层面上 是一个类
锁的释放

1、以获取锁的线程执行完同步代码,释放锁

2、线程执行发生异常,jvm会让线程释放锁

在finally中必须释放锁,不然容易造成线程死锁
锁的获取 假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待 Lock 可以设置尝试获取锁或者获取锁一定时间超时后失败
锁状态 无法判断 可以判断
控制等待和唤醒 结合加锁对象的 wait() 和 notify()、notifyAll() 结合 Condition 的 await() 和 signal()、signalAll() 方法
锁类型 可重入 不可中断 非公平 可重入 可判断 可公平/非公平(两者皆可,构造函数参数控制)
性能 少量同步 大量同步

ref: https://blog.csdn.net/qq_39521554/article/details/81130442

为什么有了synchronized,还需要Lock?

二者都是可重入锁,那么为什么要有两个呢?既然存在,那么就一定是有意义的。synchronized是Java中的一个关键字,而Lock是Java1.5后在java.util.concurrent.locks包下提供的一种实现同步的方法,那么显然的,synchronized一定是有什么做不到的或者缺陷,才导致了Lock的诞生。

synchronized的缺点

1)当一个代码块被synchronized修饰的时候,一个线程获取到了锁,并且执行代码块,那么其他的线程需要等待正在使用的线程释放掉这个锁,那么释放锁的方法只有两种,一种是代码执行完毕自动释放,一种是发生异常以后jvm会让线程去释放锁。那么如果这个正在执行的线程遇到什么问题,比如等待IO或者调用sleep方法等等被阻塞了,无法释放锁,而这时候其他线程只能一直等待,将会特别影响效率。那么有没有一种办法让其他线程不必一直傻乎乎的等在这里吗?

2)当一个文件,同时被多个线程操作时,读操作和写操作会发生冲突,写操作和写操作会发生冲突,而读操作和读操作并不会冲突,但是如果我们用synchronized的话,会导致一个线程在读的时候,其他线程想要读的话只能等待,那么有什么办法能不锁读操作吗?

3)在使用synchronized时,我们无法得知线程是否成功获取到锁,那么有什么办法能知道是否获取到锁吗?有,Lock接口

Lock的使用和原理

使用实例:https://www.cnblogs.com/huangbw/p/8516024.html 

原理分析:https://blog.csdn.net/michaelgo/article/details/81481068

原文地址:https://www.cnblogs.com/frankcui/p/10819673.html