Java 线程 — synchronized、volatile、锁
2018-02-28 09:06
120 查看
线程同步基础
synchronized 和volatile是Java线程同步的基础。synchronized
将临界区的内容上锁,同一时刻只有一个进程能访问该临界区代码使用的是内置锁,锁一个时刻只能被一个线程持有,可以重入(表示一个处于synchronized代码中的线程可以进入另外一个使用synchronized的代码快,比如:方法A和方法B同时使用synchronized修饰,在方法A中调用了方法B,调用某个线程调用方法A的时候不会造成死锁,因为synchronized是可重入的锁,线程在进入方法A的时候获得了当前对象的锁,但是此时这个线程依然可以获得方法B的synchronized锁)
synchronized修饰不同对象时获得的锁:
修饰普通方法:获得的锁是当前对象
修饰静态方法:获得的锁是当前类class
修饰代码块:取决于具体的锁对象
在Java的同步方法中synchronized是比较重量级的锁,而且不够灵活,jvm提供了更轻量的volatile,jdk提供了更灵活的Lock。
volatile
在多处理器的CPU架构下,因为每个处理器都有自己的缓存,线程访问变量的时候会读取缓存,多个线程读取的缓存不一样会导致每个线程得到的值不一样。使用该关键字的效果是:处理器将缓存写回到内存
处理器将缓存写回到内存的时候会导致其他处理器的内存失效
作用
保证可见性,Java内存模型(JMM)确保所有线程看到的这个变量的值是一致的只保证简单操作的原子性(保证变量简单赋值操作的原子性,如:temp = 1,不保证复杂操作的原子性,如:temp++)
内存语义(就是内存会做的操作)
写:当写一个volatile的变量时,JMM把该线程对应的本地缓存中的共享变量刷新到主内存读:当读一个volatile变量时,JMM把该线程对应的本地缓存置为无效,线程接下来将从主存中读取共享变量
问题:上面提到的刷新操作是对这个本地内存刷新,还是只刷新volatile变量?
解答:是刷新整个本地缓存,包括其他共享变量
CAS
CAS:Compare And Switch,在Java中是通过调用C/C++写的本地方法完成的,C又调用了CPU的cmpxchg指令完成的。一般来说有三个值:内存值V,期望值A,更新值B,如果内存值和期望值相等,则用更新值B替换内存值A,否则什么也不做
锁
什么叫锁:锁其实就是维护一种状态,比如一个int状态值state,state变量对于所有线程可见,线程A将state改为1的时候(假设,当然根据具体的需要可以设为对应的值)表示上锁的状态,线程在试图修改state的时候,发现是1,说明其他线程已经改过,线程B则进入阻塞状态,当线程A释放锁的时候,也就是将state改为0的时候,唤醒线程B,线程B会重新试图获取锁,也就是修改state的值,如果state为0,那么修改成功,线程B获得锁偏向锁:为了让之前获得过该锁的线程更容易获得锁(获得锁的代价更低,不需要CAS加锁和解锁),因为Hotspot的作者研究发现:大多数情况下锁不仅不存在竞争,而且总是由同一线程多次获得
内存语义
获取锁:当线程获取锁时,JMM会把线程对应的本地缓存中的共享变量刷新到主存释放锁:当线程释放锁时,JMM会把线程对应的本地缓存置为无效
对比volatile的和锁的内存语义,volatile的写——锁的获取,volatile的读——锁的释放
释放锁的线程在释放锁之前可见的变量,在获取锁的线程获取锁之后也可以看见这些变量,volatile也一样
锁的实现
利用volatile的读-写内存语义利用CAS(CompareAndSet)附带的volatile读-写内存语义(因为在实现CAS的时候汇编会有一个lock前缀,这个前缀会带来和volatile相同的内存语义)
一些零碎的知识点:
JVM在类初始化阶段(Class加载后,且被线程使用前),JVM会获取一个锁,这个锁可以同步多个线程对同一个类的初始化
锁参考
CAS参考
相关文章推荐
- Java线程(二):线程同步synchronized和volatile
- java 线程之synchronized,volatile,原子类,Lock锁相关
- Java并发(一):线程安全与不安全、volatile、synchronized
- Java线程(二):线程同步synchronized和volatile
- java多线程学习一线程安全之内存、synchronized、volatile
- Java线程(二):线程同步synchronized和volatile
- Java线程(二):线程同步synchronized和volatile
- 谈谈java线程锁synchronized关键字和volatile关键字
- Java线程(二):线程同步synchronized和volatile
- Java线程(二):线程同步synchronized和volatile(转)
- Java线程中的volatile和synchronized的比较
- Java线程(二):线程同步synchronized和volatile
- Java线程(二):线程同步synchronized和volatile
- Java线程(二):线程同步synchronized和volatile
- 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition
- java线程5 volatile和synchronized关键字 .
- Java 线程 — synchronized、volatile、锁
- Java 线程概述: 线程种类、状态,原子性、内存可见性、synchronized、volatile
- Java线程(二)----线程同步synchronized和volatile
- Java线程(二):线程同步synchronized和volatile