volatile

Understanding volatile asm vs volatile variable

徘徊边缘 提交于 2019-11-30 21:32:03
问题 We consider the following program, that is just timing a loop: #include <cstdlib> std::size_t count(std::size_t n) { #ifdef VOLATILEVAR volatile std::size_t i = 0; #else std::size_t i = 0; #endif while (i < n) { #ifdef VOLATILEASM asm volatile("": : :"memory"); #endif ++i; } return i; } int main(int argc, char* argv[]) { return count(argc > 1 ? std::atoll(argv[1]) : 1); } For readability, the version with both volatile variable and volatile asm reads as follow: #include <cstdlib> std::size_t

Is it legal to optimize away stores/construction of volatile stack variables?

醉酒当歌 提交于 2019-11-30 19:38:20
I noticed that clang and gcc optimize away the construction of or assignment to a volatile struct declared on the stack, in some scenarios. For example, the following code: struct nonvol2 { uint32_t a, b; }; void volatile_struct2() { volatile nonvol2 temp = {1, 2}; } Compiles on clang to: volatile_struct2(): # @volatile_struct2() ret On the other hand, gcc does not remove the stores, although it does optimize the two implied stores into a single one: volatile_struct2(): movabs rax, 8589934593 mov QWORD PTR [rsp-8], rax ret Oddly, clang won't optimize away a volatile store to a single int

Synchronize write access to Volatile field (Cheap read-write block)

时间秒杀一切 提交于 2019-11-30 19:12:05
Let's say I have the following class that will be read heavily, but only written to occasionally. It will be used in a multi-threaded web app, so it needs to be thread safe: public class Foo { private volatile String foo; public String getFoo() { return foo; } public synchronized String setFoo(String in) { this.foo = in; } } Java Concurrency ( http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html ) states that this is a fragile way to protect write access while improving read access. What is a stronger alternative to this pattern? Or any alternative if foo will need to mutable

Java内存模型

久未见 提交于 2019-11-30 19:01:11
为什么定义Java内存模型?现代计算机体系大部是采用的对称多处理器的体系架构。每个处理器均有独立的寄存器组和缓存,多个处理器可同时执行同一进程中的不同线程,这里称为处理器的乱序执行。在Java中,不同的线程可能访问同一个共享或共享变量。如果任由编译器或处理器对这些访问进行优化的话,很有可能出现无法想象的问题,这里称为编译器的重排序。除了处理器的乱序执行、编译器的重排序,还有内存系统的重排序。因此Java语言规范引入了Java内存模型,通过定义多项规则对编译器和处理器进行限制,主要是针对可见性和有序性。 三个基本原则:原子性、可见性、有序性。 Java内存模型涉及的几个关键词:锁、volatile字段、final修饰符与对象的安全发布。其中:第一是锁,锁操作是具备happens-before关系的,解锁操作happens-before之后对同一把锁的加锁操作。实际上,在解锁的时候,JVM需要强制刷新缓存,使得当前线程所修改的内存对其他线程可见。第二是volatile字段,volatile字段可以看成是一种不保证原子性的同步但保证可见性的特性,其性能往往是优于锁操作的。但是,频繁地访问 volatile字段也会出现因为不断地强制刷新缓存而影响程序的性能的问题。第三是final修饰符,final修饰的实例字段则是涉及到新建对象的发布问题。当一个对象包含final修饰的实例字段时

夯实Java基础系列17:一文搞懂Java多线程使用方式、实现原理以及常见面试题

妖精的绣舞 提交于 2019-11-30 19:00:19
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 文章首发于我的个人博客: www.how2playlife.com Java中的线程 Java之父对线程的定义是: 线程是一个独立执行的调用序列,同一个进程的线程在同一时刻共享一些系统资源(比如文件句柄等)也能访问同一个进程所创建的对象资源(内存资源)。java.lang.Thread对象负责统计和控制这种行为。 每个程序都至少拥有一个线程-即作为Java虚拟机(JVM)启动参数运行在主类main方法的线程。在Java虚拟机初始化过程中也可能启动其他的后台线程。这种线程的数目和种类因JVM的实现而异。然而所有用户级线程都是显式被构造并在主线程或者是其他用户线程中被启动。 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。在这之前,首先让我们来了解下在操作系统中进程和线程的区别:   进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。(进程是资源分配的最小单位)   线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。

设计模式——单例模式的一种比较好的写法

别说谁变了你拦得住时间么 提交于 2019-11-30 18:41:49
单例模式的一种比较好的写法 package com.volvane.JOffer.test; public class DoubleCheckSingleton { private static DoubleCheckSingleton instance; private DoubleCheckSingleton() { } /** * getInstance 进行了两次判空,第一次判空是为了不必要的同步,第二次判空为了在instance 为 null 的情况下创建实例 * 既保证了线程安全且单例对象初始化后调用getInstance又不会进行同步锁判断 * <p> * 优点:资源利用率高,效率高 * 缺点:第一次加载稍慢,由于java处理器允许乱序执行,偶尔会失败 * * @return */ public static DoubleCheckSingleton getInstance() { if (instance == null) { synchronized (DoubleCheckSingleton.class) { /* * 第二次判空,是因为,第一次的时候判空的时候, * 如果又两个线程a,b同时进“if (instance == null) {”后, * 假设线程a先拿到锁,则b等待 ,a创建了个instance对象,释放锁后, * 线程b进入

netty(五) channel

送分小仙女□ 提交于 2019-11-30 18:29:55
问题 channel 是如何处理发送一半中断后继续重发的 channel 具体作用是什么 概述 这一节我们将介绍 Channel 和内部接口 Unsafe .其中Unsafe 是内部接口,聚合在Channel 中协助网络读写操作相关的操作,设计初衷就是 Channel 的内部辅助类,不应该被用户使用。 继承类分析 继承关系链 : AbstractChannel -> AbstractNioChannel -> AbstractNioByteChannel -> NioSocketChannel 如下图 从以上的类结构我们也要学习一下类的构建,各个类实现应该实现的功能,最后生成的具体类具有不同的功能。 AbstractChannel ,保存以下重要的字段 ,主要 - EventLoop - localAddress - remoteAddress - unsafe - DefaultChannelPipleline - Future类 和 Promise类 等 AbstractNioChannel,从类名可以看出和nio 中 Channel 相关,注册,监听 private final SelectableChannel ch; protected final int readInterestOp; private volatile SelectionKey selectionKey

const、volatile、mutable的用法

六眼飞鱼酱① 提交于 2019-11-30 17:15:47
const 、 volatile 、 mutable 的 用法 const 修饰普通变量和指针 const 修饰变量,一般有两种写法: const TYPE value; TYPE const value; 这两种写法在本质上是一样的。它的含义是: const 修饰的类型为 TYPE 的变量 value 是不可变的。对于一个非指针的类型 TYPE ,无论怎么写,都是一个含义,即 value 值不可变。 例如: const int nValue ; //nValue 是 const int const nValue ; //nValue 是 const 但是对于指针类型的 TYPE ,不同的写法会有不同情况: l 指针本身是常量不可变 (char*) const pContent; l 指针所指向的内容是常量不可变 const (char) *pContent; (char) const *pContent; l 两者都不可变 const char* const pContent; 识别 const 到底是修饰指针还是指针所指的对象,还有一个较为简便的方法,也就是沿着 * 号划一条线: 如果 const 位于 * 的左侧,则 const 就是用来修饰指针所指向的变量,即指针指向为常量; 如果 const 位于 * 的右侧, const 就是修饰指针本身,即指针本身是常量。 const

9.28技术随笔

北城余情 提交于 2019-11-30 16:21:14
先立几个flag:1. 一周要至少更新一篇随笔,博客复述是对学习过程的记录,也考验自己对技术的理解。2.等秋招尘埃落定,写一篇面经。3.牛客网的在线编程题不许停。 今天遇到的技术盲点: 1.DNS 将域名转成IP地址 2.虚拟内存 操作系统把一部分硬盘当成内存来用,避免运行的程序过大的时候内存崩掉。它的大小是由CPU的寻址空间以及物理盘的剩余空间决定的。例如32位的系统,寻址空间即32位,最大支持4G(2的32次方)的虚拟空间,64位的系统最大支持8G的虚拟内存空间。 3.ArrayList 和vector的扩容 当存储空间不足时,ArrayList默认增加原始空间的50%,vector默认增加两倍(即*2)。 ArrayList无参构造是,分配的空间是0,带参构造时直接分配内存。ArrayList list = new ArrayList<>(20); 构造的时候就分配了20个内存空间,没有经过扩容。 4.volatile关键字 一般和synchronized比较。 volatile 是变量修饰符,synchronized可以修饰类、变量、代码段; volatile只能保证修改可见性,synchronized保证修改可见性及变量的原子性(即同一时刻只允许一个线程修改该变量)。 volatile不会造成线程的阻塞,synchronized有可能造成线程的阻塞。 5

ConcurrentHashMap

◇◆丶佛笑我妖孽 提交于 2019-11-30 16:20:29
一、引入背景(Why) 1. 在多线程环境下,HashMap的put会导致扩容,扩容引起死循环,导致CPU使用率100% 2. 可以使用HashTable和Collections.synchronizedMap(hashMap)可以解决多线程的问题 3. HashTable和Collections.synchronizedMap(hashMap)对读写进行加一个 全局锁 ,一个线程读写map的元素,其余线程必须等待,性能不好 4. ConcurrentHashMap也加了锁,但是只锁了map的一部分,其余线程可以继续读写没锁住的部分,优化了操作性能 二、JDK1.7的实现(了解):Segment分段锁+HashEntry+ReentrantLock 1. HashEntry是键值对,用来存储数据 2. 桶是由若干个HashEntry连接起来的链表 3. Segment分段锁继承ReentrantLock,每个Segment对象锁住若干个桶 4. 一个ConcurrentHashMap实例中,包含由若干个Segment对象组成的数组 5. HashEntry->HashBucket->Segment->ConcurrentHashMap,一层一层被包含 三、JDK1.8的实现(理解):Node+CAS+Synchronized,锁的粒度更小 1. 数据结构