`
007007jing
  • 浏览: 42769 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

可见性(visibility)的问题是Java多线程应用中的错误的根源

阅读更多

看下面一段代码,预想的输出结果为 42

public class NoVisibility {
    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread {
        public void run() {
            while (!ready)
                Thread.yield();
            System.out.println(number);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new ReaderThread().start();
        number = 42;
        ready = true;
    }
}


此段代码有可能输出 0 或者 reader线程死循环
导致这种错误出现的原因

  • CPU 内部的缓存:现在的CPU一般都拥有层次结构的几级缓存。CPU直接操作的是缓存中的数据,并在需要的时候把缓存中的数据与主存进行同步。因此在某些时刻,缓存中的数据与主存内的数据可能是不一致的。某个线程所执行的写入操作的新值可能当前还保存在CPU的缓存中,还没有被写回到主存中。这个时候,另外一个线程的读取操作读取的就还是主存中的旧值。
  • CPU的指令执行顺序:在某些时候,CPU可能改变指令的执行顺序。这有可能导致一个线程过早的看到另外一个线程的写入操作完成之后的新值。
  • 编译器代码重排:出于性能优化的目的,编译器可能在编译的时候对生成的目标代码进行重新排列。


因为在没有同步机制的下,语句的执行顺序不能得到保证。尽管我们得代码number的复制在ready之前,但这并不能保证jvm内部执行也会按照这个顺序,导致读线程出现错误。
更详细内容请参考:Java深度历险(三)——Java线程​:基本概念、可见性与同步

 

分享到:
评论

相关推荐

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

    Java多线程编程中,原子性、可见性和有序性是三个关键的概念,它们确保了多线程环境下的正确性。 1. 原子性(Atomicity) 原子性指的是一个操作不可被中断,要么全部执行,要么完全不执行。在Java中,非原生类型的...

    关于Java变量的可见性问题Java开发Java经验技巧共

    此外,了解变量可见性也有助于理解和解决多线程环境中的并发问题,如通过使用volatile关键字确保多线程环境下的变量可见性。 总的来说,Java变量的可见性是编程实践中不可或缺的一部分,熟练掌握这一概念能够帮助...

    并发编程基础知识,java内存模型及多线程、volatile

    ### 并发编程基础知识,Java内存模型及多线程、volatile #### Java内存模型(JMM) Java内存模型(Java Memory ...通过深入理解Java内存模型和多线程的相关概念,可以更好地处理并发问题,构建高效稳定的并发应用程序。

    Java内存模型--原子性;有序性;可见性1

    在Java编程语言中,内存模型(Java Memory Model, JMM)是理解和解决多线程并发问题的关键。本文将深入探讨JMM中的三个核心概念:原子性、有序性和可见性。 ### 1. 原子性(Atomicity) 原子性是指一个操作或多个...

    JAVA线程操作

    Java内存模型(JMM, Java Memory Model)是Java虚拟机(JVM)中用于描述程序执行过程中的内存可见性、有序性和一致性的一种抽象模型。它定义了程序中的各种变量(包括实例字段、静态字段和数组元素)的访问规则,...

    Java并发性编程(阿里巴巴)培训ppt

    Java并发性编程是Java开发中的重要领域,尤其是在大型企业如阿里巴巴这样的公司中,高效地处理多线程环境下的任务是至关重要的。这份“Java并发编程(阿里巴巴).ppt”很可能包含了关于如何在Java中安全、高效地进行...

    基于内存模型的Java并发编程.zip

    内存模型是并发编程的基础,它定义了多线程环境下共享变量的可见性、有序性和一致性。本资料“基于内存模型的Java并发编程”深入探讨了Java内存模型(JMM)以及如何在实际编程中利用其特性来编写高效且线程安全的...

    java 内存模型 jsr-133

    ### Java内存模型JSR-133详解 #### 引言 Java内存模型(Java Memory Model,简称JMM)是...通过对这份文档的深入研究,开发者可以更加熟练地处理多线程环境下的数据一致性问题,从而编写出更高质量的并发应用程序。

    Java 80 道面试题及答案.docx

    1. 伪共享(False Sharing): 伪共享是多线程系统中一个众所周知的性能问题,发生在不同处理器的上的线程对变量的修改依赖于相同的缓存行。 2. Busy Spin: Busy Spin 是一种在不释放 CPU 的基础上等待事件的技术,...

    JAVA-内存模型.docx

    在多线程环境中,为了确保数据的一致性和可见性,JMM定义了一系列的规则来控制这些操作。 - **变量的存储与读取**:对象最终存储在内存中,但在实际系统中,编译器、运行时环境、处理器或系统缓存可能会有不同的...

    core java concurrency

    通过以上并发概念、内存模型、标准同步机制、线程及并发工具类的介绍,Java开发者能够更好地理解并发编程的基础,并能够设计和实现稳定且高效的多线程应用程序。在多核处理器成为主流的今天,掌握Java并发编程是每个...

    Java内存模型

    Java内存模型(Java Memory Model,简称JMM)是Java编程语言规范中定义的一个抽象概念,用于描述程序中各个变量(包括实例域、静态域和数组元素)在不同线程之间的可见性和有序性。JMM的存在是为了处理多线程环境下...

    Java内存模型详解

    Java内存模型(Java Memory Model,JMM)是Java虚拟机规范中定义的一种抽象概念,它描述了Java程序中各个变量(包括实例域、静态域和数组元素)的可见性、有序性以及在多线程环境下的行为。JMM的主要目标是解决由于...

    java名词速查表 java名词速查表

    - 访问修饰符用来控制类、方法、变量等的可见性和访问范围,Java中有四种访问修饰符: - `public`:完全公开; - `protected`:对同一包内的类或子类公开; - `default`(无修饰符):仅对同一包内的类公开; - ...

    Java培训PPT

    Java中的`volatile`关键字可以保证可见性。 - **有序性**(Ordering): Java内存模型允许编译器和处理器重新排序操作以优化性能,但这可能会影响多线程程序的正确性。`volatile`, `synchronized`, 和`Lock`等机制...

    jmm模型ppt基本概念介绍

    JMM围绕原子性、有序性、可见性展开,确保了Java程序在多线程环境下的正确执行。 JMM基本概念 1. 主内存(Main Memory):JMM中的主内存属于共享数据区域,包括堆和方法区,主要存储的是Java实例对象、共享的类...

    java基础名词解释汇总.docx

    "Java基础名词解释汇总" Java基础名词解释汇总面向对象程序设计(Object-Oriented Programming)是指java基础名词解释汇总的主要内容。...Visibility是可见性,表达了方法和实例变量对其他类和包的访问控制。

    java内存模型.pdf

    Java内存模型在并发编程中非常重要,因为它规定了线程如何和何时可以看到由其他线程修改的变量的值,从而保证了多线程程序的正确性。 在Java内存模型中,有两个重要的区域:堆内存(Heap Memory)和工作内存...

    Java.Concurrency.in.Practice.pdf

    如何在多线程中执行任务,使用线程池(Thread Pools)和执行器框架(Executor Framework)等高级工具。 7. **取消和关闭(Cancellation and Shutdown)** 处理任务的取消机制,以及在服务停止时的线程安全问题。...

    软件编程词汇表(一些编程词汇的解释)

    受保护区域是指在多线程环境中,为了防止并发访问而导致的数据不一致性,而使用同步机制(如锁)保护的代码段。通过确保每次只有一个线程可以访问受保护区域,可以有效地避免竞态条件。 #### 33. 堆 (Heap) 堆是...

Global site tag (gtag.js) - Google Analytics