线程同步基础

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也一样

锁的实现

  1. 利用volatile的读-写内存语义
  2. 利用CAS(CompareAndSet)附带的volatile读-写内存语义(因为在实现CAS的时候汇编会有一个lock前缀,这个前缀会带来和volatile相同的内存语义)

一些零碎的知识点:

  • JVM在类初始化阶段(Class加载后,且被线程使用前),JVM会获取一个锁,这个锁可以同步多个线程对同一个类的初始化

锁参考

CAS参考

Java 线程 — synchronized、volatile、锁的更多相关文章

  1. Java 线程安全 与 锁

    Java 线程安全 与 锁 多线程内存模型 线程私有栈内存 每个线程 私有的内存区域 进程公有堆内存 同一个进程 共有的内存区域 为什么会有线程安全问题? 多个线程同时具有对同一资源的操作权限,又发生 ...

  2. 【Java线程安全】锁

    Java都有哪些锁? synchronized 和 reentranlock是最常见的,其中前者又JVM提供实现,后者有专门对应的java.util.concurrent包提供:同时后者功能更加丰富. ...

  3. Java线程同步与锁

    一.synchronized synchronized锁什么?锁对象.可能锁对象包括: this, 临界资源对象,Class类对象. 1,同步方法 synchronized T methodName( ...

  4. Java线程安全与锁优化

    线程安全的严谨定义: 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交题执行,也不需要进行额外的同步,或者调用方法进行其他任何操作,调用这个对象的行为都可以或者正确的结果,那么这 ...

  5. 【Thread】java线程之对象锁、类锁、线程安全

    说明: 1.个人技术也不咋滴.也没在项目中写过线程,以下全是根据自己的理解写的.所以,仅供参考及希望指出不同的观点. 2.其实想把代码的github贴出来,但还是推荐在初学的您多亲自写一下,就没贴出来 ...

  6. Java线程安全与锁优化,锁消除,锁粗化,锁升级

    线程安全的定义 来自<Java高并发实战>"当多个线程访问一个对象的时候,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方法的时候进行任何 ...

  7. 【Java线程】volatile的适用场景

    http://www.ibm.com/developerworks/cn/java/j-jtp06197.html 把代码块声明为 synchronized,有两个重要后果,通常是指该代码具有 原子性 ...

  8. java多线程synchronized volatile解析

    先简单说说原子性:具有原子性的操作被称为原子操作.原子操作在操作完毕之前不会线程调度器中断.即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行.在Java中,对除了l ...

  9. Java线程synchronized(一)

    线程安全概念:当多个线程访问某一个类(对象或方法)时,这个对象始终都能表现出正确的行为,那么这个类(对象或方法)就是线程安全的. synchronized:可以在任意对象及方法上加锁,而加锁的这段代码 ...

随机推荐

  1. 解决KDE桌面环境下Eclipse崩溃的问题--让Eclipse使用特定的GTK2主题运行

    最近在Kubuntu14.04上安装Eclipse,由于Ubuntu软件中心中的版本太老(3.8),而且会自动安装OpenJDK,于是到官网下载最新的4.4版.(Luna,代号很有亲切感有木有,女神万 ...

  2. python学习之——计算给出代码中注释、代码、空行的行数

    题目:计算给出代码中注释.代码.空行的行数 来源:网络 思路:注释行以 ‘#’开头,空行以 ‘\n’ 开头,以此作为判断 def count_linenum(fname): fobj = open(f ...

  3. (转)ajax.dll,ajaxpro.dll的区别和用法

    ASP.NET AjaxPro的应用 1.首先下载AjaxPro组件.并将AjaxPro.dll引用到网站(或项目). 2.修改Web.config.在 <system.web> 元素中添 ...

  4. python学习笔记-Day6(2)

    xml处理模块 xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融 ...

  5. SUSE Linux Enterprise Server 11 软件源

    1.添加软件源 zypper ar http://ftp5.gwdg.de/pub/opensuse/discontinued/distribution/11.4/repo/oss oss zyppe ...

  6. 管理表空间和数据文件<六>

    数据库管理 -- 管理表空间和数据文件  介绍 表空间是数据库的逻辑组成部分.从物理上讲,数据库数据存放在数据文件中:从逻辑上讲,数据库则是存放在表空间中,表 空间由一个或多个数据文件组成. 数据库 ...

  7. 拾遗:『Linux Capability』

    『Linux Capability』 For the purpose of performing permission checks, traditional UNIX implementations ...

  8. nginx apache负载均衡测试

    apache配置 (监听内网ip和端口) Listen 10.163.170.8:8001 Listen 10.163.170.8:8002 Listen 10.163.170.8:8003 < ...

  9. Wall--POJ1113(极角排序+求凸包)

    http://poj.org/problem?id=1113 题目大意:现在要给n个点,让你修一个围墙把这些点围起来,距离最小是l 分析  :现在就是求凸包的周长然后再加上一个圆的周长 #includ ...

  10. Jplayer歌词同步显示插件

    http://blog.csdn.net/wk313753744/article/details/38758317 1.该插件是一个jquery的编写的跟jplayer实现歌词同步的插件,最终效果如图 ...