`
weiweishouwang
  • 浏览: 6688 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JAVA线程02:可见性和有序性

阅读更多

    Java线程有两个特性,可见性和有序性。多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变量来实现。

    可见性:当一个对象在多个内存中都存在副本时,如果一个内存修改了共享变量,其它线程也应该能够看到被修改后的值。拿上篇博文中的例子来说明,在多个线程之间共享了PrintString类的一个对象,这个对象是被创建在主内存(堆内存)中,每个线程都有自己的工作内存(线程栈),工作内存存储了主内存PrintString对象的一个副本,当线程操作PrintString对象时,首先从主内存复制PrintString对象到工作内存中,然后执行代码printer.print(),改变了builder值,最后用工作内存PrintString刷新主内存PrintString。因此上篇博文的例子没有保证可见性。

    有序性:多个线程执行时,CPU对线程的调度是随机的,我们不知道当前程序被执行到哪步就切换到了下一个线程,一个最经典的例子就是银行汇款问题,一个银行账户存 款100,这时一个人从该账户取10元,同时另一个人向该账户汇10元,那么余额应该还是100。那么此时可能发生这种情况,A线程负责取款,B线程负责 汇款,A从主内存读到100,B从主内存读到100,A执行减10操作,并将数据刷新到主内存,这时主内存数据100-10=90,而B内存执行加10操 作,并将数据刷新到主内存,最后主内存数据100+10=110,显然这是一个严重的问题,我们要保证A线程和B线程有序执行,先取款后汇款或者先汇款后取款。

    为保证可见性和有序性,需要引入同步机制。JAVA关键字volatile机制保证了线程间的同步。

 

    volatile:一个变量可以被volatile修饰,在这种情况下内存模型(主内存和线程工作内存)确保所有线程可以看到一致的变量值。volatile变量具有可见性特性,但是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。Volatile 变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。因此,单独使用 volatile 还不足以实现计数器、互斥锁或任何具有与多个变量相关的不变式(Invariants)的类(例如 “start <=end”)。只能在有限的一些情形下使用 volatile 变量替代锁。要使 volatile 变量提供理想的线程安全,必须同时满足下面两个条件:

  • 对变量的写操作不依赖于当前值。
  • 该变量没有包含在具有其他变量的不变式中。

    第一个条件的限制使 volatile 变量不能用作线程安全计数器。虽然增量操作(x++)看上去类似一个单独操作,实际上它是一个由读取-修改-写入操作序列组成的组合操作,必须以原子方式执行,而 volatile 不能提供必须的原子特性。实现正确的操作需要使 x 的值在操作期间保持不变,而 volatile 变量无法实现这点。大多数编程情形都会与这两个条件的其中之一冲突,使得 volatile 变量不能像 synchronized 那样普遍适用于实现线程安全。

    因此,虽然volatile变量可以提供优于锁的性能优势,但是不能保证线程安全,所以最好不要用volatile保证性能安全,除非您确实是一个编程高手。

   

    锁的讲解见下篇。

分享到:
评论

相关推荐

    Java线程安全问题_动力节点Java学院整理

    不同的平台,内存模型是不一样的,但是jvm的内存模型规范是统一的。...JVM定义了自己的内存模型,屏蔽了底层平台内存管理细节,对于java开发人员,要清楚在jvm内存模型的基础上,如果解决多线程的可见性和有序性。

    JAVA线程安全及性能的优化

    不同的平台,内存模型是不一样的,但是jvm的内存模型规范是统一的。...JVM定义了自己的内存模型,屏蔽了底层平台内存管理细节,对于java开发人员,要清楚在jvm模型的基础上,如果解决多线程的可见性和有序性。

    了解Java多线程的可见性与有序性

    主要介绍了了解Java多线程的可见性与有序性,在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。,需要的朋友可以参考下

    java并发理论基础、可见性、原子性、有序性详解

    本资源涵盖了Java并发编程的理论基础和实践,主要包括可见性、原子性和有序性的详细介绍,以及多线程的使用原因、好处和坏处等方面的内容。 Java并发编程是一种高效的编程技术,通过多线程实现将计算过程中不必要的...

    Java多线程中提到的原子性和可见性、有序性1

    如果应场景需要个更范围的原性保证,Java内存模型还提供了lock和unlock操作来满这种需求,尽管虚拟机未把lock与unlock操作直接开放给户使,但是却

    Java并发编程实战 02Java如何解决可见性和有序性问题

    那么这篇文章就先解决其中的可见性和有序性问题,引出了今天的主角:Java内存模型(面试并发的时候会经常考核到) 什么是Java内存模型? 现在知道了CPU缓存导致可见性、编译优化导致了有序性问题,那么最简单的方式...

    java多线程安全性基础介绍.pptx

    java多线程安全性基础介绍 线程安全 正确性 什么是线程安全性 原子性 竞态条件 i++ 读i ++ 值写回i 可见性 JMM 由于cpu和内存加载速度的差距,在两者之间增加了多级缓存导致,内存并不能直接对cpu可见。 ...

    解开Volatile的面纱V1.1

    解决并发问题,我们一般需要从原子性、可见性和有序性三方面入手,借助Java关键字及各种同 步工具类来实现。 原子性、可见性、有序性三特性: 1. 原子性:原子性就是说一个操作不能被打断,要么执行完要么不执行。 2...

    java并发编程理论基础精讲

    本资源为您提供了关于 Java ...volatile 关键字: 解释 volatile 关键字的作用,探讨如何使用 volatile 实现线程间的可见性和有序性。 通过这份资源,将为您提供实用的指导,帮助您构建更稳定、可靠的多线程应用程序。

    14、深入理解并发可见性、有序性、原子性与JMM内存模型(1).pdf

    14、深入理解井发可见性、有序性、原子性与JMM内存模型 (1).pdf 15、CPU缓存架构详解&高性能内存队列Disruptor 实战 (1).pdf 16、常用并发设计模式精讲 (1).pdf designpattern.zip disruptor.zip forkjoin.zip jmm(1...

    java面试题-java-interview-questions-master.zip

    java面试题_java-interview-questions-master.zip2、在 Java 程序中怎么保证多线程的运行安全? 出现线程安全问题的原因一般都是三个原因: 1、 线程切换带来的原子性问题 解决办法:使用多线程之间同步...

    Java的线程安全内存模型.docx

    什么是线程安全问题? 当 多个线程 同时共享同一个 全局变量 ...o可见性:多个线程访问同一变量,一个线程修改了变量的值,其他线程可以立即看到修改的值 o有序性:程序按照代码的顺序先后执行(与指令重排有关)

    Java多线程安全问题和锁

    多线程安全问题和锁 文章目录多线程安全问题和锁线程在jvm中的特点锁的出现synchronized 关键字-监视器锁monitor lock死锁的产生和避免 ...可见性是指线程对共享数据的访问是否对其他的线程可见. A

    详解java多线程的同步控制

    同步控制是并发程序必不可少的重要手段,本文我们将通过重入锁、读写锁、信号量、倒计数器和循环...保证了共享内存的原子性、可见性、有序性 JMM原理图 线程在访问主内存中的变量时并不是直接对主存中的变量进行读写,

    Test2.java

    java多线程的通讯共享数据就是共享内存,共享内存主要有可见性和有序原子性。java 内存原型JMM解决可见有序,线程锁synchronized所解决它的原子性。 JMM内存原型:java可以在不同操作系统不同硬件存储逻辑下运行的...

    Java并发编程.docx

    o可见性 :一个线程对共享变量的修改,另一个线程能立刻看到。 缓存 可导致可见性问题。 o原子性 :一个或多个CPU执行操作不被中断。 线程切换 可导致原子性问题。 o有序性 :编译器优化可能导致指令顺序发生...

    【2018最新最详细】并发多线程教程

    7.三大性质总结:原子性、可见性以及有序性 8.初识Lock与AbstractQueuedSynchronizer(AQS) 9.深入理解AbstractQueuedSynchronizer(AQS) 10.彻底理解ReentrantLock 11.深入理解读写锁ReentrantReadWriteLock 12.详解...

    完结13章一课掌握Java并发编程精髓

    并发情况主要会引出三个基本概念,分别是原子性、可见性、有序性三个基本概念 Java中线程的状态分为6种: 1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。 2. 运行(RUNNABLE):Java线程中将就绪...

    Java多线程之volatile关键字及内存屏障实例解析

    volatile是JVM提供的一种最轻量级的同步机制,因为Java内存模型为volatile定义特殊的访问规则,使其可以实现Java内存模型中的两大特性:可见性和有序性。这篇文章主要介绍了Java多线程之volatile关键字及内存屏障,...

    Java中Volatile关键字步骤

    基本概念 Java内存模型中的可见性,原子性和有序性 可见性:  可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉。通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是...

Global site tag (gtag.js) - Google Analytics