synchronized是Java面试的常客,我们需要掌握它的基本使用,比如同步代码块、同步普通方法、同步静态方法,以及他们的区别,当然这是最初级的。高级点的就是需要掌握synchronized的实现原理,比如对象头、synchronized的锁优化、锁的膨胀过程,这篇文章就是介绍synchronized的锁膨胀过程。该过程其实很多小伙伴都不知道,18年面试的时候问了不下于20个人,没有一个回答比较好的,甚至有将近一半的人都不知道有这个。synchronized同步锁一共具有四种状态:无锁、偏向锁、轻量级锁、重量级锁,他们会随着竞争情况逐渐升级,此过程为不可逆。所以synchronized锁膨
DCL,即DoubleCheckLock,中卫双重检查锁定。其实DCL很多人在单例模式中用过,LZ面试人的时候也要他们写过,但是有很多人都会写错。他们为什么会写错呢?其错误根源在哪里?有什么解决方案?下面就随LZ一起来分析问题分析我们先看单例模式里面的懒汉式:publicclassSingleton{privatestaticSingletonsingleton;privateSingleton(){}publicstaticSingletongetInstance(){if(singleton==null){singleton=newSingleton();}returnsingleton;
前篇博客【死磕Java并发】-----深入分析volatile的实现原理中已经阐述了volatile的特性了:volatile可见性;对一个volatile的读,总可以看到对这个变量最终的写;volatile原子性;volatile对单个读/写具有原子性(32位Long、Double),但是复合操作除外,例如i++;JVM底层采用“内存屏障”来实现volatile语义下面LZ就通过happens-before原则和volatile的内存语义两个方向介绍volatile。volatile与happens-before在这篇博客【死磕Java并发】-----Java内存模型之happend-bef
在执行程序时,为了提供性能,处理器和编译器常常会对指令进行重排序,但是不能随意重排序,不是你想怎么排序就怎么排序,它需要满足以下两个条件:在单线程环境下不能改变程序运行的结果;存在数据依赖关系的不允许重排序如果看过LZ上篇博客的就会知道,其实这两点可以归结于一点:无法通过happens-before原则推导出来的,JMM允许任意的排序。as-if-serial语义as-if-serial语义的意思是,所有的操作均可以为了优化而被重排序,但是你必须要保证重排序后执行的结果不能被改变,编译器、runtime、处理器都必须遵守as-if-serial语义。注意as-if-serial只保证单线程环境
在上篇博客(【死磕Java并发】-----深入分析volatile的实现原理)LZ提到过由于存在线程本地内存和主内存的原因,再加上重排序,会导致多线程环境下存在可见性的问题。那么我们正确使用同步、锁的情况下,线程A修改了变量a何时对线程B可见?我们无法就所有场景来规定某个线程修改的变量何时对其他线程可见,但是我们可以指定某些规则,这规则就是happens-before,从JDK5开始,JMM就使用happens-before的概念来阐述多线程之间的内存可见性。在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须存在happens-before关系。happens-be
通过前面一章我们了解了synchronized是一个重量级的锁,虽然JVM对它做了很多优化,而下面介绍的volatile则是轻量级的synchronized。如果一个变量使用volatile,则它比使用synchronized的成本更加低,因为它不会引起线程上下文的切换和调度。Java语言规范对volatile的定义如下:Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量。上面比较绕口,通俗点讲就是说一个变量如果用volatile修饰了,则Java可以确保所有线程看到这个变量的值是一致的,如果某个线程对volatile修饰的共享变
记得刚刚开始学习Java的时候,一遇到多线程情况就是synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字“同步”,也成为了我们解决多线程情况的百试不爽的良药。但是,随着我们学习的进行我们知道synchronized是一个重量级锁,相对于Lock,它会显得那么笨重,以至于我们认为它不是那么的高效而慢慢摒弃它。诚然,随着JavsSE1.6对synchronized进行的各种优化后,synchronized并不会显得那么重了。下面跟随LZ一起来探索synchronized的实现机制、Java是如何对它进行了优化、锁优化机制、锁的存储结
【死磕Java并发】系列是LZ在2017年写的第一个死磕系列,一直没有做一个合集,这篇博客则是将整个系列做一个概览。先来一个总览图:【高清图,请关注“Java技术驿站”公众号,回复:脑图JUC】【死磕Java并发】—–深入分析synchronized的实现原理synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性。深入分析synchronized的内在实现机制,锁优化、锁升级过程。【死磕Java并发】—–深入分析volatile的实现原理volatile可以保证线程可见性且提供了一定的有序性,但是无法保证原子性。在JV