【java并发编程实战】第二章:对象的共享
1.重要的属性
可见性,不变性,原子性
1.1可见性
当一个线程修改某个对象状态的时候,我们希望其他线程也能看到发生后的变化。
在没有同步的情况下,编译器和处理器会对代码的执行顺序进行重排。以提高效率。重排后的顺序是不可预知的,所以在多线程中无法对执行结果进行判断
看下面的代码
public class NoVisibility {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
@Override
public void run() {
while (!ready) {
System.out.println(">>>");
}
System.out.println(1/number);
}
}
public static void main(String[] args) {
new ReaderThread().start();
number = 1;
ready = true;
}
}
上面的执行结果可能会一直执行下去,也可能抛错。我们期望number=1以后,ready=true执行,最后输出1/1=1,由于重排,可能导致ready先初始化,然后线程读取到的还是ready=true,number=0.导致异常.
最低安全性:线程在没有同步的情况下可能会得到失效的值,但是至少这个值是之前某个线程设置的,而不是随机值。但有一个例外,看下面
其中提到了一个很有趣的非原子的64位操作
jvm内存模型规定,变量的读写操作都要原子性,但是有个例外,非volatile修饰的long和double这64位的操作,jvm允许将64位的读写操作分成2个32位的操作,就可能导致读取到的某个值的高32位和另外一个值的低32位。
除非用volatile或者锁保护起来。
1.1.1 volatile
基础
1.弱同步机制,volatile更新后的值将会通知其他线程。
2.变量修饰后,jvm或处理器不会对其进行指令重排。
3.不会被缓存在寄存器或者其他处理器看不到的地方。所以读取的值都是最新的。
其中与加锁不同的是,加锁可以保证原子性和可见性,但是volatile修饰后只能保证可见性。
1.1.2 threadlocal
threadlocal是为了防止可变的单实例变量或全局变量进行共享。jdbc就是采用了threadlocal。
threadlocal这里只描述场景和并发的关系。需要独立篇幅进行原理分析。
1.1.3
解决并发问题的另一个解决方案,不变形对象。不可变对象一定是线程安全的。
对象不可变的满足条件:
①对象创建后就不可修改
②对象的所有域都是final修饰
③对象是正确创建的,创建期间没有this溢出被其他地方修改。
final修饰的List,Map等都是可以继续添加元素。可以采用Collections.unmodifiableXXX()。其实它的原理不过是实现一个Map接口。重写了put和remove等修改的时候进行异常抛出的操作。
private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {
private static final long serialVersionUID = -1034234728574286014L;
private final Map<? extends K, ? extends V> m;
UnmodifiableMap(Map<? extends K, ? extends V> m) {
if (m==null)
throw new NullPointerException();
this.m = m;
}
// 省略
public V put(K key, V value) {
throw new UnsupportedOperationException();
}
public V remove(Object key) {
throw new UnsupportedOperationException();
}
public void putAll(Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
}
【java并发编程实战】第二章:对象的共享的更多相关文章
- JAVA并发编程实战---第二章:线程安全性
对象的状态是指存储在状态变量中的数据.对象的状态可能包括其他依赖对象的域.例如HashMap的状态不仅存储在HashMap本身,还存储在许多Map.Entry对象中.对象的状态中包含了任何可能影响其外 ...
- Java并发编程实战4章
第4章主要介绍如何构造线程安全类. 在设计线程安全类的过程中,需要包含以下三个基本要素: 找出构成对象状态的所有变量. 找出约束状态变量的不变性条件. 建立对象状态的并发访问管理策略. 构造线程安全类 ...
- Java并发编程实战3章
1.同步包括两方面:原子性和可见性. 2.可见性:因为在多线程程序中,如果没有采用正确的同步,有些线程就会得到失效数据. Java内存模型要求,变量的读取操作和写入操作都必须是原子操作,但对于非vol ...
- Java并发编程实战---第六章:任务执行
废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...
- 《Java并发编程实战》/童云兰译【PDF】下载
<Java并发编程实战>/童云兰译[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062521 内容简介 本书深入浅出地介绍了Jav ...
- 《java并发编程实战》笔记
<java并发编程实战>这本书配合并发编程网中的并发系列文章一起看,效果会好很多. 并发系列的文章链接为: Java并发性和多线程介绍目录 建议: <java并发编程实战>第 ...
- [书籍翻译] 《JavaScript并发编程》 第二章 JavaScript运行模型
本文是我翻译<JavaScript Concurrency>书籍的第二章 JavaScript运行模型,该书主要以Promises.Generator.Web workers等技术来讲解J ...
- Java并发编程实战 03互斥锁 解决原子性问题
文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...
- Java并发编程实战 04死锁了怎么办?
Java并发编程文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 前提 在第三篇 ...
- Java并发编程实战——读后感
未完待续. 阅读帮助 本文运用<如何阅读一本书>的学习方法进行学习. P15 表示对于书的第15页. Java并发编程实战简称为并发书或者该书之类的. 熟能生巧,不断地去理解,就像欣赏一部 ...
随机推荐
- 裁剪插件jCrop
为大家介绍个插件:jCrop.这个插件被我用在了多个项目中,如通过画热力图来查看某块地方用户的浏览数,放大缩小拖动选框来实时预览所选区域的图片病裁剪,设置头像是选框必须要是正方形,它有着丰富的配置参数 ...
- JS面向对象、prototype、call()、apply()
一. 起因 那天用到prototype.js于是打开看看,才看几行就满头雾水,原因是对js的面向对象不是很熟悉,于是百度+google了一把,最后终于算小有收获,写此纪念一下^_^. prototyp ...
- openstack kilo python cinderclient
➜ ~ pythonPython 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on ...
- treap数组版
然而就是将指针的地方换成int引用 就是存个代码 #include<cstdio> #include<iostream> #include<cstdlib> #in ...
- 使用Newtonsoft.json 解决 Asp.Net MVC DateTime类型数据Json格式化问题
解决思路 众所周知,MVC中调用的微软的组件JavaScriptSerialer...,格式DateTime类型数据需要在客户端专门解. 还知道,NewtonSoft.json可以“正确”的格式化Da ...
- JS无限添加HTML到指定位置
用JS把HTML添加到指定位置有两种写法,一种是用字符串,一种是用javascript中的方法 第一种: 用字符串写 <h2>利用JS无限添加一个相同部分</h2> <h ...
- List<T>转换为二维数组
public <T> Object[][] toArrays(List<T> data){ Object[][] o=new Object[data.size()][20]; ...
- Oracle必备知识.
一.基本数据类型 1.字符数据类型 char varchar2 long 三者区别: I.char固定长度字符串,存储字母数字值,列长度可以是 1 到 2000 个字节. II.varc ...
- Mac openssl 和curl源码编译
1.先编译openssl, 下载源码后解压,终端进入源码目录,输入命令配置编译环境:./Configure darwin64-x86_64-cc 等待配置完成后,输入make 和make insta ...
- 服务器操作nginx相关操作命令
服务器操作nginx相关操作命令 登录服务器: ssh root@0.0.0.0 -p 22100 启动nginx: /usr/local/nginx/sbin/nginx 查看nginx是否启动 p ...