标签 ‘ volatile

从单例模式到Happens-Before

本文主要从简单的单例模式为切入点,分析单例模式可能存在的一些问题,以及如何借助Happens-Before分析、检验代码在多线程环境下的安全性。

阅读全文

您还有心跳吗?超时机制分析

问题描述

在C/S模式中,有时我们会长时间保持一个连接,以避免频繁地建立连接,但同时,一般会有一个超时时间,在这个时间内没发起任何请求的连接会被断开,以减少负载,节约资源。并且该机制一般都是在服务端实现,因为client强制关闭或意外断开连接,server端在此刻是感知不到的,如果放到client端实现,在上述情况下,该超时机制就失效了。本来这问题很普通,不太值得一提,但最近在项目中看到了该机制的一种糟糕的实现,故在此深入分析一下。 阅读全文

Java并发中正确使用volatile

作者:一粟   整理和翻译自Twitter实时搜索的PPT

前几天并发编程群里有同学对volatile的用法提出了疑问,刚好我记得Twitter有关实时搜索的这个PPT对这个问题解释的很清晰并有一个实际的应用场景,于是周末把这个问题摘录了一些和并发相关的内容如下: 阅读全文

有关“双重检查锁定失效”的说明

原文地址 译者:丁一

双重检查锁定(以下称为DCL)已被广泛当做多线程环境下延迟初始化的一种高效手段。

遗憾的是,在Java中,如果没有额外的同步,它并不可靠。在其它语言中,如c++,实现DCL,需要依赖于处理器的内存模型、编译器实行的重排序以及编译器与同步库之间的交互。由于c++没有对这些做出明确规定,很难说DCL是否有效。可以在c++中使用显式的内存屏障来使DCL生效,但Java中并没有这些屏障。

阅读全文

聊聊我对Java内存模型的理解

所有的编程语言中都有内存模型这个概念,区别于微架构的内存模型,高级语言的内存模型包括了编译器和微架构两部分。我试图了解了Java、C#和Go语言的内存模型,发现内容基本大同小异,只是这些语言在具体实现的时候略有不同。

我们来看看Java内存模型吧,提到Java内存模型大家对这个图一定非常熟悉: 阅读全文

深入理解Java内存模型(四)——volatile

本文属于作者原创,原文发表于InfoQ:http://www.infoq.com/cn/articles/java-memory-model-4

volatile的特性

当我们声明共享变量为volatile后,对这个变量的读/写将会很特别。理解volatile特性的一个好方法是:把对volatile变量的单个读/写,看成是使用同一个锁对这些单个读/写操作做了同步。下面我们通过具体的示例来说明,请看下面的示例代码:

class VolatileFeaturesExample {
    //使用volatile声明64位的long型变量
    volatile long vl = 0L;

    public void set(long l) {
        vl = l;   //单个volatile变量的写
    }

    public void getAndIncrement () {
        vl++;    //复合(多个)volatile变量的读/写
    }

    public long get() {
        return vl;   //单个volatile变量的读
    }
}

阅读全文

volatile是否能保证数组中元素的可见性?

在javaeye有位朋友问了我一个非常好的问题。

问题

一个线程向volatile的数组中设置值,而另一个线程向volatile的数组中读取。
比如seg.setValue(2),随后另一个线程调用seg.getValue(2),前一个线程设置的值对读取的线程是可见的吗?

我看书上说volatile的数组只针对数组的引用具有volatile的语义,而不是它的元素。

ConcurrentHashMap中也有这样的代码,我很疑惑,希望得到你的解答,谢谢。

阅读全文

Java内存模型Cookbook(四)指南(Recipes)

原文:http://gee.cs.oswego.edu/dl/jmm/cookbook.html

作者:Doug Lea 翻译:丁一

  1. 前言
  2. 指令重排
  3. 内存屏障
  4. 多处理器
  5. 指南

单处理器(Uniprocessors)

如果能保证正在生成的代码只会运行在单个处理器上,那就可以跳过本节的其余部分。因为单处理器保持着明显的顺序一致性,除非对象内存以某种方式与可异步访问的IO内存共享,否则永远都不需要插入屏障指令。采用了特殊映射的java.nio buffers可能会出现这种情况,但也许只会影响内部的JVM支持代码,而不会影响Java代码。而且,可以想象,如果上下文切换时不要求充分的同步,那就需要使用一些特殊的屏障了。

阅读全文

同步和Java内存模型(五)Volatile

原文链接: http://gee.cs.oswego.edu/dl/cpj/jmm.html

作者:Doug lea 译者:杜建雄  校对者:方腾飞

Volatile

从原子性,可见性和有序性的角度分析,声明为volatile字段的作用相当于一个类通过get/set同步方法保护普通字段,如下:

final class VFloat {
    private float value;

    final synchronized void set(float f) { value = f; }
    final synchronized float get()       { return value; }
}

与使用synchronized相比,声明一个volatile字段的区别在于没有涉及到锁操作。但特别的是对volatile字段进行“++”这样的读写操作不会被当做原子操作执行。

另外,有序性和可见性仅对volatile字段进行一次读取或更新操作起作用。声明一个引用变量为volatile,不能保证通过该引用变量访问到的非volatile变量的可见性。同理,声明一个数组变量为volatile不能确保数组内元素的可见性。volatile的特性不能在数组内传递,因为数组里的元素不能被声明为volatile。

阅读全文

同步和Java内存模型

原文:http://gee.cs.oswego.edu/dl/cpj/jmm.html

作者:Doug Lea 译者:程晓明,萧欢,杜建雄  校对:方腾飞,丁一,欧振聪

目录

  1. 引言
  2. 原子性
  3. 可见性
  4. 有序性
  5. Volatile

JMM Cookbook(一)指令重排

原文地址:http://gee.cs.oswego.edu/dl/jmm/cookbook.html 第一章 译者:欧振聪 校对:李同杰

  1. 前言
  2. 指令重排
  3. 内存屏障
  4. 多处理器
  5. 指南

指令重排

对于编译器的编写者来说,Java内存模型(JMM)主要是由禁止指令重排的规则所组成的,其中包括了字段(包括数组中的元素)的存取指令和监视器(锁)的控制指令。

Volatile与监视器

JMM中关于volatile和监视器主要的规则可以被看作一个矩阵。这个矩阵的单元格表示在一些特定的后续关联指令的情况下,指令不能被重排。下面的表格并不是JMM规范包含的,而是一个用来观察JMM模型对编译器和运行系统造成的主要影响的工具。

阅读全文

聊聊并发(一)深入分析Volatile的实现原理

本文属于作者原创,原文发表于InfoQ:http://www.infoq.com/cn/articles/ftf-java-volatile

引言

在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。它在某些情况下比synchronized的开销更小,本文将深入分析在硬件层面上Inter处理器是如何实现Volatile的,通过深入分析能帮助我们正确的使用Volatile变量。

阅读全文

return top