Java锁优化的思路和方法

92 阅读2分钟

锁的优化

锁优化的思路和方法
锁本质上是一种阻塞的方法,相对于无锁的同步方法性能上会差一点。
对锁的优化只是一定程度上尽可能提高锁的性能:
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() //保证线程安全下获取值

在这里插入图片描述