易截截图软件、单文件、免安装、纯绿色、仅160KB

JAVA高级:多核线程 volatile原理与技巧

 
为什么使用volatile比同步代价更低?
同步的代价, 主要由其覆盖范围决定, 如果可以降低同步的覆盖范围, 则可以大幅提升程序性能.
而volatile的覆盖范围仅仅变量级别的. 因此它的同步代价很低.
volatile原理是什么?
volatile的语义, 其实是告诉处理器, 不要将我放入工作内存, 请直接在主存操作我.(工作内存详见java内存模型)
因此, 当多核或多线程在访问该变量时, 都将直接操作主存, 这从本质上, 做到了变量共享.
volatile的有什么优势?
1, 更大的程序吞吐量
2, 更少的代码实现多线程
3, 程序的伸缩性较好
4, 比较好理解, 无需太高的学习成本
volatile有什么劣势?
1, 容易出问题
2, 比较难设计
volatile运算存在脏数据问题
volatile仅仅能保证变量可见性, 无法保证原子性.
volatile的race condition示例:
public class TestRaceCondition {
private volatile int i = 0;
public void increase() {
i++;
}
public int getValue() {
return i;
}
}
当多线程执行increase方法时, 是否能保证它的值会是线性递增的呢?
答案是否定的.
原因:
这里的increase方法, 执行的操作是i++, 即 i = i + 1;
针对i = i + 1, 在多线程中的运算, 本身需要改变i的值.
如果, 在i已从内存中取到最新值, 但未与1进行运算, 此时其他线程已数次将运算结果赋值给i.
则当前线程结束时, 之前的数次运算结果都将被覆盖.
即, 执行100次increase, 可能结果是 < 100.
一般来说, 这种情况需要较高的压力与并发情况下, 才会出现.
如何避免这种情况?
解决以上问题的方法:
一种是 操作时, 加上同步.
这种方法, 无疑将大大降低程序性能, 且违背了volatile的初衷.
第二种方式是, 使用硬件原语(CAS), 实现非阻塞算法
从CPU原语上, 支持变量级别的低开销同步.
CPU原语-比较并交换(CompareAndSet),实现非阻塞算法
什么是CAS?
cas是现代CPU提供给并发程序使用的原语操作. 不同的CPU有不同的使用规范.
在 Intel 处理器中,比较并交换通过指令的 cmpxchg 系列实现。
PowerPC 处理器有一对名为“加载并保留”和“条件存储”的指令,它们实现相同的目地;
MIPS 与 PowerPC 处理器相似,除了第一个指令称为“加载链接”。
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)
什么是非阻塞算法?
一个线程的失败或挂起不应该影响其他线程的失败或挂起.这类算法称之为非阻塞(nonblo


相关文档:

java入门

 Java学习从入门到精通 
一、 JDK (Java Development Kit) 
JDK是整个Java的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具和Java基础的类库(rt.jar)。不论什么Java应用服务器实质都是内置了某个版本的JDK。因此掌握JDK是学好Java的第一步。最主流的J ......

Java NIO API详解

 
Java NIO API详解
在JDK
1.4以前,Java的IO操作集中在java.io这个包中,是基于流的阻塞(blocking)API。对于大多数应用来说,这样的API使用很方
便,然而,一些对性能要求较高的应用,尤其是服务端应用,往往需要一个更为有效的方式来处理IO。从JDK 1.4起,NIO
API作为一个基于缓冲区,并能提供非阻塞(non-blo ......

JAVA读取资源文件的N种方法

 
如何读取资源文件:
(一)
Properties props = new Properties();   
props.load(new FileInputStream("db.properties"));
(二)
blog.properties文件如下
dbdriver=oracle.jdbc.driver.OracleDriver
dburl=jdbc:oracle:thin:@127.0.0.1:1521:ora92
dbuser=blog
dbpwd=blog
- ......

Java编程基础

 在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的对系统设计人员来讲就不那么重要
了;而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主
要 ......

Java 程序内存分析

   java程序内存主要分为了2个部分,包括 stack segment(栈内存)、heap segment(堆内存)。
    在分析Java程序内存分配情况时,我们从下面这个经常被使用的例子开始吧。
    下面程序将打印什么呢?
   
Java代码
String s1 = new S ......
© 2009 ej38.com All Rights Reserved. 关于E健网联系我们 | 站点地图 | 赣ICP备09004571号