锁的优化
锁优化的思路和方法
锁本质上是一种阻塞的方法,相对于无锁的同步方法性能上会差一点。
对锁的优化只是一定程度上尽可能提高锁的性能:
a.减少所持有时间 只对有同步要求的代码块进行加锁
b.减少锁粒度 以HashMap为例,实现它的同步,只需要对其get、set方式使用互斥量同步即可实现其线程安全
c.锁分离 使用读写锁,区分读、写操作
d.锁粗化 两个同步模块之间如果存在执行时间段的代码块,合并两个同步模块,核心思想减少获取锁的次数。
e.锁消除 避免对不可能被共享的对象进行加锁操作
f.虚拟机内部对锁的优化:偏向锁、互斥锁、自旋锁(使用synchronized时的默认操作)
- 偏向锁:锁会偏向于当前已经占有锁的线程
- 轻量级锁:轻量级锁是一种快速的锁定方法
- 自旋锁:利用互斥锁,达到只有一个线程访问该对象的目的 ,同时不会使调用者睡眠。
虚拟机内部尝试使用锁的步骤:
先尝试使用偏向锁,失败的情况下,
再尝试使用轻量级锁,失败的情况下,
再 尝试使用自旋锁,失败的情况下,
尝试使用使用普通锁,再失败的情况下,
对线程进行OS层面的挂起
ThreadLocal
ThreadLocal来管理局部变量,从而实现具备变量的线程同步
场景:局部变量如果被多线程访问,要实现对有数据冲突的变量的要进行线程同步(数据可能会变化)
//只改Bank类,其余代码与上同
public class Bank{
//使用ThreadLocal类管理共享变量account
private static ThreadLocal<Integer> account = new ThreadLocal<Integer>(){
@Override
protected Integer initialValue(){
return 100;
}
};
public void save(int money){
account.set(account.get()+money);
}
public int getAccount(){
return account.get();
}
}
ThreadLocal.set()//保证线程安全的情况下设定值 set不能使用对象的拷贝(不能使用引用,只能 new一个对象)
ThreadLocal.get() //保证线程安全下获取值