Lock的总结

在J.U.C(java.util.concurrent)出现之前,java的synchronize/synchronized关键字给我们的并发带来了极大的便利和好处,当然,有利必有弊,它的锁粒度、死锁问题也一直被诟病,但是很少有人知道虚拟机对并发做了哪些优化,虚拟机会将锁粒度分为几种,偏向锁,轻量级锁(自旋锁),重量级锁(互斥锁),轻量级锁的出现主要是因为JVM作者通过测试数据发现锁经常由同一个线程进出,为了降低 systemcall来阻塞唤醒线程的开销,从而引入了此锁,通过对java对象的对象头的锁标志位操作来实现,有1bit是表明此对象是否被偏向锁占用 的,偏向锁优先级比较低,当轻量级锁,重量级锁到达的时候,偏向锁会自动“让位”,当没有线程争用的时候它才会偷偷占用资源,轻量级锁最典型的表现就是自 旋锁了,同样是为了避免systemcall(涉及到操作系统用户态,内核态的切换),不过它的场景适用于线程争用没有那么激烈的场景以及同步代码块较小 的场景(但是它会有ABA问题),为什么呢?比如我的同步块里只有一行代码System.out.println("test"),进入和退出非常快,那 么因为这个阻塞其他等待的线程就显得没啥必要,有systemcall(涉及到操作系统用户态,内核态的切换)是一部分原因,因为你同步块的代码并不是原 子性的(除了volatile变量的简单赋值,就算是C++,也会依赖一些好的编译器才能达到i++这种操作的原子性,引自thinking in java),当你执行到同步代码的一半(System.out.println("test")的“一半”要好好理解下),操作系统的线程上下文发生切 换,被切换到的线程因为这行非常短的代码被阻塞放入阻塞队列,是不是很不值呢,此时自旋锁的用武之地就到了,最典型的自旋锁其实在jdk的 AtomicXXX类里就有了
Lock的总结_第1张图片
 此 方法意思为:拿到堆内的旧值比对一下,如果和自己期望的值一样再把新值set进去,此操作要依赖cpu的cas指令支持(但是具体它会不会跨越内存栅栏不 得而知,据我所知java只有volatile关键字是跨越内存栅栏直接操作堆内存的),它是不会阻塞等待锁的线程的,只会“无限”的自旋,当然你也可以 覆盖这个方法根据业务需要进行优化,比如设置你想要的自旋次数而不是一直循环下去,同样自旋锁除了ABA问题之外还有一个问题就是单核无效,为什么呢,占用锁的线程已经占用了一个核,自旋的线程还需要一个额外的核来运行自旋,当然在如今计算机如此发达这个问题也不算问题了,自旋锁有两种著名的算法(在我看 来其实都一个意思)CLH自旋锁和MCS自旋锁,J.U.C的重入锁就是用CLH算法实现的(算法很美,但是目前在好多知识没实践的情况下我是没时间去玩 了),最后就是我们的重量级锁了,俗称互斥锁,这个就不用我过多介绍了,它的实现还是蛮复杂的,jvm屏蔽了这些,但是J.U.C是单独的纯java锁实现,要看懂那套算法还是要下很多功夫的,也是很重量级的锁,纵向对比的话肯定是互斥锁性能最差,横向对比的话不同的锁适用不同的场景,所以有时候需要设计适合自己业务场景的锁,但是这种需要“十年磨一剑”,对操作系统,算法,数据结构甚至硬件都有要求,当然了,最好的还是设计lock-free算法,锁只是一种下策,所以怎么设计无锁并发的lock-free算法是要跟业务搭钩滴,不过有一个disruptor的框架很强悍,代码精细粒度达到了CPU级,不过还没时间去研究。JVM还有很多其他的优化,比如锁膨胀,锁削除,不过这是和synchronize关键字挂钩的,要想利用纯java的实现就要借助J.U.C的同步工具包,这些包的类几乎底层都要依赖Unsafe这个类,这个类是内部使用的(oracle在考虑以后把它放给开发者),提供了很多底层的操作,cas操作就来自于它,还有就是文件映射nio的分配堆外内存的mappedbytebuffer类(周志明的深入理解java虚拟机用那个方法模拟了一种特殊的内存溢出,堆外内存溢出,堆内存不是越大越好,如果使用了文件映射技术就要考虑下内存溢出的风险了,当然就算没用到此技术也要留给操作系统足够的执行空间,好事不能都被你占了对吧)等等。
最近和哥们聊天有点感悟,自己也做了很多思考总结说来就那么几点:
1、技术要钻吗,以后我要转型吗
新闻说27后IT男是隔几年减半,这个我还没想明白,老实说挺爱技术的,放下不知道舍得不
2、测试
上面提到的偏向锁的由来就是因为jvm作者通过测试发现的,包括jdk里一些jconsole,jstack等的测试并发工具都用的不熟,最近进了一家不错的公司,体验了一把大公司的氛围,让我有点小佩服。我的沟通还是辣么捉鸡- -#
3、工具
eclipse用的不熟啊,idea其实用的也一般般
4、业务
其实自己深钻技术的后果就是对业务不熟,即使技术再好,做的东西也是稀烂,所以以后会花更大精力在业务上,当然技术也不会拉下

你可能感兴趣的:(Lock的总结)