一、多线程同步内部如何实现的?
wait/notify,synchronized,ReentrantLock等
二、ReentrantLock与synchronized各版本及比较
1、表格描述
ReentrantLock | synchronized | |
---|---|---|
版本 | jdk1.5出现(因为synchronized的那个时候性能太低) | 一直存在(jdk1.6开始优化) |
区别 | 1、Java级别的锁,一般不需要调用操作系统函数 2、有丰富的api 3、有公平非公平之分 4、有条件锁 | 只有重量级的锁,需要调用操作系统的函数,就是切换内核来操作(因为jdk1.6之后优化了) |
性能 | 1、jdk1.8之前,RentrantLock性能比syncronized高,因为它是Java级别的锁,而synchronized是重量级的锁; 2、jdk1.6之后,synchronized性能逐渐提高,作为sun公司的儿子,他们不断优化它,出现了偏向锁、轻量级锁级重量级锁膨胀升级,所以到了jdk1.8时两种锁性能无法比较,基本上持平 3、ConcurrentHashMap1.8之前用的是ReentrantLock,jdk1.8的时候又改回了synchronized。 |
2、文字描述
synchronized:
synchronized在jdk1.6之前实现同步是重量级(cpu切换,内核--用户)的锁,调用操作系统的函数(本地方法,private native void start0();---openjdk-----c----os----启动)
jdk1.6及之后,JVM级别的锁(尽量借助java函数就可以解决,不调用native方法),有偏向锁、轻量级、重量级升级
wait要和sync一起使用,park和wait的区别:wait让线程阻塞前,必须通过synchronized获取同步锁,否则会抛异常:可以参考park/wait/sleep
synchronized=== os jdk1.6之前 cpu线程交替执行需要到操作系统,需要切换到内核,需要时间,内核才可以操作操作系统的东西 内核不给开发人员操作
ReentrantLock:
诞生,因为jdk1.6之前sync是重量级锁,性能低,所以它诞生了,ConcurrentHashMapjdk1.8之前用ReentrantLock,1.8及之后又用了synchronized,因为synchronized是sun公司子的儿子,所以肯定会优化,现在已经优化的不比ReentrantLock差,jdk1.8synchronized和ReentrantLock 性能基本一致,但是ReentrantLock提供了丰富的api,有条件锁,公平锁等 而sync没有这些功能,没有公平之分
ReentrantLock===jdk1.6及之后 java级别 大部分都是java jvm执行,线程交替执行在java级别解决了,效率特别高,还有一部分是在os下执行的,用到os的api
交替执行:没有竞争(无需入队,不用os的api)
非交替执行:有竞争(需要入队,需要调用os的api park阻塞,unpark解除阻塞)