美文网首页
Java多线程 JMM volatile

Java多线程 JMM volatile

作者: StephenLau | 来源:发表于2019-05-07 17:14 被阅读0次

本质

Java多线程安全问题的本质原因,有线程的写操作。如果多个线程对同一资源进行读,是没有问题的。但如果一个线程写到一半,其他线程读,就会出问题。因此需保证写的操作完成后才能读。

以下内容精简自:http://tutorials.jenkov.com/java-concurrency/index.html

Java Memory Model

The Internal Java Memory Model

The Java Memory Model showing references from local variables to objects, and from object to other objects.

Thread stack又可以称为Call stack。在某线程中“call”的方法中的Local variables都会保存在Thread stack中,这里的Local variables包括primitive type和object reference。

不管在哪个Thread中new的Object都保存在Heap中,Object的member variables保存在Heap中,但是Object的method中存在的Local variables依然保存在Thread Stack中。
Static class variables也在Heap中。

Hardware Memory Architecture

The division of thread stack and heap among CPU internal registers, CPU cache and main memory.

一个modern computer hardware architecture会对存储进行分层缓存,本质是因为访问速度的不同。CPU进行读写操作的时候会有从底层向上read从顶层向下flush的过程。

Thread stack和Heap都是存在于Main memory的,但是Thread stack和Heap又可能出现在CPU caches或CPU registers中.
这种不确定性会产生两个主要的问题:

  • Thread updates (writes) shared variables的可见性(Visibility)
  • 不同线程读写shared variables时产生的竞争状态(Race conditions)

Visibility of Shared Objects

多个线程共享一个Object的情况下,没恰当使用volatile和synchronization的话,一个线程对shared object的改变可能对其他线程不可见。

Visibility Issues in the Java Memory Model.

可以使用volatile解决上述问题。

volatile

volatile是易变的意思。用来标记一个Java variable存储在 main memory中。

Full volatile Visibility Guarantee

Java volatile关键字的可变性保证是超过 volatile修饰的变量本身的。详细的读这里

因为JVM会Instruction Reordering,volatile关键字还提供“happens-before”保证。

对其他变量的读写不能reorder到对volatile变量的写之后。位于volatile的写后面的对其他变量的读写还是可能reorder到前面的。也就是From after to before is allowed, but from before to after is not allowed.

对其他变量的读写不能reorder到对volatile变量的读之前。也就是From before to after is allowed, but from after to before is not allowed.

volatile is Not Always Enough

它的使用场景:

只有一个线程读写某volatile变量,其他线程只读此变量,可以保证线程读到的是最新的值。

如果两个线程都对shared variable进行读写,使用volatile是不够的!

Race Conditions

Race Condition Issues in the Java Memory Model.

两个线程同时读取同一个Object再进行修改的话,会出现Race Conditions的问题。

可以用synchronized block解决竞争机制,synchronized blocks保证其中的所有变量会从Main memory中读取,并且当 Thread 退出synchronized block时, 所有更新后的变量会flushed回Main memory,不管变量是否是volatile的。

相关文章

  • Java多线程 JMM volatile

    本质 Java多线程安全问题的本质原因,有线程的写操作。如果多个线程对同一资源进行读,是没有问题的。但如果一个线程...

  • 多线程编程那些事

    多线程编程那些事 标签:HPC、多线程、JMM、Volatile、锁、CPU多核构架、Happens before...

  • java学习笔记

    1.volatile 2.JMM(java内存模型) 3.volatile代码可见性 4.volatile代码不保...

  • JMM简介

    Java Memory Model(JMM)java内存模型,区别与java内存结构。JMM定义了一套在多线程读写...

  • Java-多线程-JMM&Volatile

    一、现代计算机模型 冯诺依曼计算机是由控制器、运算器、存储器、输入、输出构成。但现代计算机模型要复杂的多,其中CP...

  • 死磕Java——volatile的理解

    一、死磕Java——volatile的理解 1.1.JMM内存模型 理解volatile的相关知识前,先简单的认识...

  • 死磕Java——volatile的理解

    一、死磕Java——volatile的理解 1.1.JMM内存模型 理解volatile的相关知识前,先简单的认识...

  • 深入理解 java volatile

    在开始讲volatile之前,我们需要对以下的内容有所了解. java 内存模型(JMM) 在java中,java...

  • (转载)全面理解Java内存模型(JMM)及volatile关键

    原文链接:全面理解Java内存模型(JMM)及volatile关键字 - CSDN博客 理解Java内存区域与Ja...

  • 多线程-JMM,volatile,synchronized

    程序产生异常,锁就会被释放。原子性:某个操作是不可分割的。在一个线程进行对代码块原子操作的时候,其他的线程必须等待...

网友评论

      本文标题:Java多线程 JMM volatile

      本文链接:https://www.haomeiwen.com/subject/zxsyoqtx.html