《Java Concurrency in Practice》之可见性(Visibility)
来源:互联网 发布:虚拟专用网络是免费的 编辑:程序博客网 时间:2024/06/05 15:35
原文:Visibility is subtle because the things that can go wrong are so counterintuitive. 译文:可见性是微妙的,因为可能出错的事情是如此的有悖常理。
public class NoVisibility {private static boolean ready;private static int number;private static class ReaderThread extends Thread {@Overridepublic void run() {while (!ready) {Thread.yield();}System.out.println(number);}}public static void main(String[] args) {new ReaderThread().start();number = 42;ready = true;} }NoVisibility可能会持续循环下去,因为读线程可能永远都看不到ready的值。
一种更奇怪的现象是会发生重排序(Reordering),NoVisibility可能会输出0,因为读线程可能看到了写入ready的值,但却没看到之后写入number的值。
在没有同步的情况下,编译器(Compiler)、处理器(Processor)和运行时(Runtime)等都可能对操作的执行顺序进行一些意想不到的调整。在缺乏足够同步的多线程程序中,要想对内存操作的执行顺序进行判断,几乎无法得出正确的结论。
一、失效数据(stale data)
NoVisibility展示(demonstrated)的一种方式,在缺乏足够的同步程序中,可能会导致令人惊讶的结果:失效数据。(原文:NoVisibility demonstrated one of the ways that insufficiently synchronized programs can cause surprising results: stale data.)
失效数据还可能会带来诸如损坏的数据结构(corrupted data structures)、不精确的计算(inaccurate computations),以及无限循环(infinite loops)等。
二、非原子的64位操作(Nonatomic 64-bit operations)
线程的最低安全性(out-of-thin-air safety),是指当线程在没有同步的情况下读取变量时,可能会得到一个失效值,但至少这个值是由之前某个线程设置的值,而不是一个随机值。
最低安全性适用于绝大数变量,但是存在一个例外:非volatile类型的64位数值变量(double and long)。Java的内存模型要求,变量的读取操作和写入操作都必须是原子操作,但对于非volatile类型的long和double变量,JVM允许将64位的读操作或写操作分解为两个32位的操作。
因此,在多线程中使用共享且可变的long和double等类型的变量也是不安全的,除非它们用volatile声明,或者由锁保护。
三、加锁和可见性(Locking and visibility)
内置锁可以用于确保某个线程以一种可预测的方式来查看另一个线程的执行结果。
在访问共享的可变变量时,我们有理由要求所有线程在同一个同步锁的规则,保证由某一个线程写的值对其它线程是可见的。否则,如果一个线程在未持有正确锁的情况下,读取某个变量,可能会看到一个失效的值。(原文:We can now give the other reason for the rule requiring all threads to synchronize on the same lock when accessing a shared mutable variable—to guarantee that values written by one thread are made visible to other threads. Otherwise, if a thread reads a variable without holding the appropriate lock, it might see a stale value.)
加锁不仅仅是与互斥性相关,也与内存的可见性相关。为了确保所有线程都能看到共享变量的最新值,读写线程必须在同一个锁上同步。(原文:Locking is not just about mutual exclusion; it is also about memory visibility. To ensure that all threads see the most up-to-date values of shared mutable variables, the reading and writing threads must synchronize on a common lock.)
0 0
- 《Java Concurrency in Practice》之可见性(Visibility)
- Java Concurrency in Practice :基础知识(重排序与可见性)
- 《Java Concurrency in Practice》之原子性(Atomicity)
- Java Concurrency in Practice
- Java Concurrency in Practice
- Java Concurrency In Practice
- 《Java Concurrency in Practice》之线程安全性
- 《Java Concurrency in Practice》之Volatile variables
- 变量可见性和volatile, this逃逸, 不可变对象, 以及安全公开--Java Concurrency In Practice C03读书笔记
- Java Concurrency In Practice Notes
- Java Concurrency in Practice 笔记
- java concurrency in practice - 1
- java concurrency in practice - 2
- Understand <Java Concurrency in Practice>
- Java Concurrency in Practice读书笔记
- 《Java Concurrency in Practice》之初识并发编程
- 《Java Concurrency in Practice》之加锁机制(Locking)
- 《Java Concurrency in Practice》之Disruptor简单类图
- Android.mk 用法解析2
- 访问SQL Server实例的常见问题
- 织梦做商城,按销量,价格等自定义模型字段排序列表解决方案
- Java队列实现
- android 中XML和对象转换利器Xstream的使用
- 《Java Concurrency in Practice》之可见性(Visibility)
- Oracle 物化视图 说明
- hbase shell使用secureCRT登录后无法backspace删除字符解决
- 使用虚拟机作为开发测试环境总结
- ubuntu有线无法上网(双系统下windows可以)--可以连接无法上网
- HttpSession框架指南
- myeclipse快捷键大全
- phpMyAdmin添加数据库独立管理用户
- hadoop遇到的问题: org.apache.hadoop.ipc.Client: Retrying connect to server异常的解决