参考文章:https://www.jianshu.com/p/2344a3e68ca9
https://cloud.tencent.com/developer/article/1369358
1、synchronized
Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块。
2、Lock
synchronized
是Java语言的关键字,是内置特性,而ReentrantLock
是一个类(实现Lock
接口的类),通过该类可以实现线程的同步。
关于Lock的具体解析可以点击传送门
3、volatile
volatile
是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。确保本条指令不会因编译器的优化而省略,且要求每次直接读值。
4、synchronized, lock和volatile区别(可见性、原子性、有序性)
属性 | Synchronized | lock | volatile | 解释 |
---|---|---|---|---|
可见性 | √ | √ | √ | 变量被操作之后,能够快速写入内存,并提醒其他线程重读,加锁是通过一个一个执行保证了可见性。 |
原子性 | √ | √ | × | 做的过程中,不要有相关的来打扰,不相关的我们也不关心,加锁是通过一个一个执行保证了流程不会被相关的打扰。 |
有序性 | √ | √ | √ | 在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。 |
5、synchronized与lock区别
类别 | synchronized | Lock |
---|---|---|
存在层次 | Java的关键字,在jvm层面上 | 是一个类 |
锁的释放 | 1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm会让线程释放锁 | 在finally中必须释放锁,不然容易造成线程死锁 |
锁的获取 | 假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待 | 分情况而定,Lock有多个锁获取的方式,具体下面会说道,大致就是可以尝试获得锁,线程可以不用一直等待 |
锁状态 | 无法判断 | 可以判断 |
锁类型 | 可重入 不可中断 非公平 | 可重入 可判断 可公平(两者皆可) |
性能 | 少量同步 | 大量同步 |