版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_37378518/article/details/85295358
synchronized关键字
- sychronized取得的锁都是对象锁,而不是把一段代码或方法(函数)当做锁。
- 锁重入功能:当一个线程得到一个对象锁后,再次请求可以再次得到该对象的锁
- 出现异常,锁自动释放
- 同步不具有继承性
class Base{
synchronized public void method(){...}
}
class Extend extends Base{
// override method, synchroized do not have Inheritance
public void method(){...}
}
- 弊端:线程A调用同步方法执行一个长时间任务时,线程B也必须等待较长时间,可使用sychronized代码块缩小范围
- sychronized应用在static方法上,使用当前java文件对应的Class类进行持锁
- sychronized与String常量池
volatile关键字
-
主要作用是使变量在多个线程间可见
-
强制线程从公共堆栈中取得变量值,而不是从线程私有数据栈获取
-
volatile非线程安全的原因
线程整个过程:
- read,load:从主存复制变量到当前线程工作内存
- use,assign:执行代码,改变共享变量值
- store,write:用工作内存数据刷新主存对应变量值
在多线程环境中,use和assign多次出现,这一操作并不是原子性,也就是在read和load之后,如果祝内存中变量发生修改后,线程工作内存中的值已经加载完成,不会产生相应的变化,也就是私有内存和公共内存中变量不同步,出现非线程安全问题。
sychronized | volatile | |
---|---|---|
性能 | 较弱 | 较好 |
修饰范围 | 方法,代码块 | 变量 |
阻塞情况 | 会阻塞 | 不会阻塞 |
可见性 | 间接保证(会将私有与公共内存数据做同步) | 有保证 |
原子性 | 原子性 | 不能保证 |
目的 | 解决变量在多个线程间的可见性 | 解决多个线程间访问资源的同步性 |
其它
方法中的变量(局部变量)是线程安全的:每个线程都会创建自己的堆栈,线程不会与其它线程共享自己栈中的内容
可重入锁:
- 自己可以再次获取自己的内部锁
- 子类可以通过“可重入锁”调用父类的同步方法