http://www.ibm.com/developerworks/library/j-jtp02244.html?S_TACT=105AGX52&S_CMP=cn-a-j
Most programmers know that thesynchronized
keyword enforces a mutex (mutual exclusion) that prevents more than one thread at a time from entering a synchronized block protected by a given monitor. But synchronization also has another aspect: It enforces certain memory visibility rules as specified by the JMM. It ensures that caches are flushed when exiting a synchronized block and invalidated when entering one, so that a value written by one thread during a synchronized block protected by a given monitor is visible to any other thread executing a synchronized block protected by that same monitor. It also ensures that the compiler does not move instructions from inside a synchronized block to outside (although it can in some cases move instructions from outside a synchronized block inside). The JMM does not make this guarantee in the absence of synchronization -- which is why synchronization (or its younger sibling, volatile) must be used whenever multiple threads are accessing the same variables.
When a thread exits a synchronized block as part of releasing the associated monitor, the JMM requires that the local processor cache be flushed to main memory. (Actually, the memory model does not talk about caches -- it talks about an abstraction,local memory, which encompasses caches, registers, and other hardware and compiler optimizations.) Similarly, as part of acquiring the monitor when entering a synchronized block, local caches are invalidated so that subsequent reads will go directly to main memory and not the local cache. This process guarantees that when a variable is written by one thread during a synchronized block protected by a given monitor and read by another thread during a synchronized block protected by the same monitor, the write to the variable will be visible by the reading thread. The JMM does not make this guarantee in the absence of synchronization -- which is why synchronization (or its younger sibling,volatile
) must be used whenever multiple threads are accessing the same variables.
synchronized
关键字的作用:
1. 作为线程间的互斥锁,防止多个线程同时访问由一个监视器保护的同步块
2. 保证内存的可见性。它可以确保,当离开同步块的时候将缓存数据刷新到内存中,当进入同步块的时候使本地缓存失效,从内存中获取最新数据。如果两个同步块被同一个监视器所保护,那么这两个同步块根据运行的时间有一个happen-before的关系,并且在后面执行的同步块中是可以看到前面那个同步块对内存的更新的。
3. 确保编译器不会将同步块中的指令移到同步块外面来(尽管在某些时候可以将同步块外面的指令移入到同步块内)
有一个疑问:
在离开同步块时,会刷新缓存到内存中,此处说的缓存的数据是不是该线程的本地缓存中的所有数据,包括不在同步块中使用的,不是volatile的?
分享到:
相关推荐
- **内存可见性问题**:不同线程间可能无法正确地看到变量的最新值,导致线程间的数据不一致。 - **并发执行问题**:当一个线程正在执行`set()`方法的同时,另一个线程尝试调用`check()`方法时,可能会导致不可预测...
6. **内存模型与并发**:Java内存模型(JMM)定义了线程之间共享变量的访问规则,确保正确同步和内存可见性。它涉及到volatile变量、synchronized关键字、final字段的语义以及线程交互的内存操作。 7. **异常处理**...
1、保证内存可见性 2、防止指令重排 此外需注意volatile并不保证操作的原子性。 (一)内存可见性 1 概念 JVM内存模型:主内存和线程独立的工作内存 Java内存模型规定,对于多个线程共享的变量...
此外,还会介绍synchronized关键字和volatile变量,用于线程同步和内存可见性。 以上就是"v2ch8"章节的主要内容,通过深入学习这些知识点,你可以掌握Java编程的基础,为后续的高级主题打下坚实的基础。无论你是...
总结来说,Java内存模型通过原子性、有序性和可见性保证了多线程环境下的数据一致性。理解并熟练运用这些概念是编写高效、线程安全的Java代码的基础。在实际开发中,应根据需求选择合适的方式来确保这三个特性,以...
Java多线程编程中,原子性、可见性和有序性是三个关键的概念,它们确保了多线程环境下的正确性。 1. 原子性(Atomicity) 原子性指的是一个操作不可被中断,要么全部执行,要么完全不执行。在Java中,非原生类型的...
根据提供的文档信息,本文将详细解析并发编程中的关键概念——原子性、可见...通过以上讨论可以看出,原子性、可见性和有序性是并发编程中非常重要的概念,正确理解和运用这些概念对于开发高质量的多线程应用至关重要。
因此,文章强调了控制多个线程对某个资源的有序访问或修改的重要性,并讨论了Java内存模型中两个主要的问题:可见性和有序性。 最后,文章总结了基于Java多线程同步的安全性研究的重要性和必要性,并提出了解决Java...
本文主要讲解了Java内存模型(JMM)中关于并发编程的三个基本概念:原子性、可见性和有序性。 原子性 原子性是指一个操作不会被线程调度机制打断,一旦开始,就一直运行到结束,中间不会有任何线程切换(context ...
在Java并发编程中,内存可见性和线程安全是核心议题。本文将探讨三个关键概念:过期数据、锁的可见性以及Volatile关键字的作用。首先,我们来看一下“过期数据”这一问题。 1. 过期数据 在并发环境中,当多个线程...
它定义了程序中各个线程如何访问和修改共享变量,以及如何确保这些操作的可见性。在JMM中,可见性是指当一个线程修改了一个共享变量的值时,其他线程能够立即看到这个修改。 在Java中,如果没有适当的同步措施,...
Java内存模型是Java虚拟机(JVM)规范中的一部分,它定义了共享内存系统中多线程程序的内存访问规则,从而确保多线程环境下的可见性和有序性。在深入理解Java内存模型之前,我们首先需要了解并发编程中的两个基本...
5. **原子性、可见性和有序性**:JMM 保证了这三个核心特性。原子性确保操作不可分割,可见性保证了线程间的内存可见性,有序性限制了编译器和处理器对指令的重排序,以避免数据竞争和一致性问题。 6. ** Happens-...
然而,并发编程也带来了一系列挑战,如线程安全、可见性、原子性和有序性问题。 **并发理论基础**: 并发编程的核心在于多线程,允许多个执行单元在同一时间执行任务,以充分利用系统资源。在Java中,通过创建...
3. `Atomic`类:`java.util.concurrent.atomic`包中的原子类,如`AtomicInteger`、`AtomicBoolean`等,它们提供的原子操作在多线程环境下可以确保操作的原子性和可见性。 4. `ThreadLocal`:虽然`ThreadLocal`主要...
在Java并发编程中,这些规则确保了内存可见性和有序性,防止了数据竞争和脏读等并发问题。开发者可以通过synchronized关键字、volatile关键字、Atomic类等方式利用JMM来实现线程安全。理解并遵循这些规则是编写正确...
JMM通过控制主内存与每个线程的本地内存之间的交互,为Java程序员提供了内存可见性的保证。 JVM对Java内存模型的实现将内存分为两部分:线程栈区和堆区。每个线程拥有自己的线程栈,其中包含了线程执行的方法调用...