【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并发编程实战简称为并发书或者该书之类的. 熟能生巧,不断地去理解,就像欣赏一部 ...
随机推荐
- 有权并查集,Poj(1988)
题目链接:http://poj.org/problem?id=1988 题目大意: 有n个从1到n编号的箱子,将每个箱子当做一个栈,对这些箱子进行p次操作,每次操作分别为以下两种之一: 输入 M x ...
- 使用taobao cnpm 源解决npm无法安装module问题
npm 安装nativescript时出现异常,一直停着不动.应该是源被墙了的问题可以使用淘宝仓库,执行下面的命令: alias cnpm="npm --registry=https://r ...
- Spring boot 集成三种拦截方式
三种拦截方式分别为: javax.servlet.Filter org.springframework.web.servlet.HandlerInterceptor org.aspectj.lang. ...
- nginx架构分析之 模块化
Nginx涉及到的模块分为核心模块.标准HTTP模块.可选HTTP模块.邮件服务模块以及第三方模块等五大类. 核心模块 核心模块是指Nginx服务器正常运行时必不可少的模块,它们提供了Nginx最基本 ...
- SQL递归查询实现组织机构树
系统用到的组织机构树,要实现对当前节点以及其子节点的查询,数据库SQL要用到递归查询,这也是我第一次接触SQL的递归查询. 先说一下什么是递归查询,简单说来是将一个树状结构存储在一张表里,比如一个表中 ...
- MySQL - Linux下安装
本安装方式仅对5.7.21版本负责. 下载地址:wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.21-linux-glibc2 ...
- Servlet学习笔记04——什么是重定向,servlet生命周期?
1.重定向 (1)什么是重定向? 服务器通知浏览器访问一个新的地址. 注: 服务器可以通过发送一个302状态码及一个 Location消息头(该消息头的值是一个地址,一般 称之为重定向地址)给浏览器, ...
- 柱状图多系列php动态实现(ec)
<?php require_once 'data.php'; $arr1=$a->sum('answer','ask_id=1'); $arr2=$a->sum('answer',' ...
- 深入理解PHP数组函数和预定义接口
一. PHP对数组的过滤 函数: array_filter(p1[,p2]) 参数p1是要过滤的数组,参数p2是自定义过滤会掉函数(可以是匿名函数) 例子: <?php $arr = ['',n ...
- python爬虫:爬取猫眼TOP100榜的100部高分经典电影
1.问题描述: 爬取猫眼TOP100榜的100部高分经典电影,并将数据存储到CSV文件中 2.思路分析: (1)目标网址:http://maoyan.com/board/4 (2)代码结构: (3) ...