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并发编程实战】第二章:对象的共享的更多相关文章

  1. JAVA并发编程实战---第二章:线程安全性

    对象的状态是指存储在状态变量中的数据.对象的状态可能包括其他依赖对象的域.例如HashMap的状态不仅存储在HashMap本身,还存储在许多Map.Entry对象中.对象的状态中包含了任何可能影响其外 ...

  2. Java并发编程实战4章

    第4章主要介绍如何构造线程安全类. 在设计线程安全类的过程中,需要包含以下三个基本要素: 找出构成对象状态的所有变量. 找出约束状态变量的不变性条件. 建立对象状态的并发访问管理策略. 构造线程安全类 ...

  3. Java并发编程实战3章

    1.同步包括两方面:原子性和可见性. 2.可见性:因为在多线程程序中,如果没有采用正确的同步,有些线程就会得到失效数据. Java内存模型要求,变量的读取操作和写入操作都必须是原子操作,但对于非vol ...

  4. Java并发编程实战---第六章:任务执行

    废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...

  5. 《Java并发编程实战》/童云兰译【PDF】下载

    <Java并发编程实战>/童云兰译[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062521 内容简介 本书深入浅出地介绍了Jav ...

  6. 《java并发编程实战》笔记

    <java并发编程实战>这本书配合并发编程网中的并发系列文章一起看,效果会好很多. 并发系列的文章链接为:  Java并发性和多线程介绍目录 建议: <java并发编程实战>第 ...

  7. [书籍翻译] 《JavaScript并发编程》 第二章 JavaScript运行模型

    本文是我翻译<JavaScript Concurrency>书籍的第二章 JavaScript运行模型,该书主要以Promises.Generator.Web workers等技术来讲解J ...

  8. Java并发编程实战 03互斥锁 解决原子性问题

    文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...

  9. Java并发编程实战 04死锁了怎么办?

    Java并发编程文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 前提 在第三篇 ...

  10. Java并发编程实战——读后感

    未完待续. 阅读帮助 本文运用<如何阅读一本书>的学习方法进行学习. P15 表示对于书的第15页. Java并发编程实战简称为并发书或者该书之类的. 熟能生巧,不断地去理解,就像欣赏一部 ...

随机推荐

  1. 有权并查集,Poj(1988)

    题目链接:http://poj.org/problem?id=1988 题目大意: 有n个从1到n编号的箱子,将每个箱子当做一个栈,对这些箱子进行p次操作,每次操作分别为以下两种之一: 输入 M x ...

  2. 使用taobao cnpm 源解决npm无法安装module问题

    npm 安装nativescript时出现异常,一直停着不动.应该是源被墙了的问题可以使用淘宝仓库,执行下面的命令: alias cnpm="npm --registry=https://r ...

  3. Spring boot 集成三种拦截方式

    三种拦截方式分别为: javax.servlet.Filter org.springframework.web.servlet.HandlerInterceptor org.aspectj.lang. ...

  4. nginx架构分析之 模块化

    Nginx涉及到的模块分为核心模块.标准HTTP模块.可选HTTP模块.邮件服务模块以及第三方模块等五大类. 核心模块 核心模块是指Nginx服务器正常运行时必不可少的模块,它们提供了Nginx最基本 ...

  5. SQL递归查询实现组织机构树

    系统用到的组织机构树,要实现对当前节点以及其子节点的查询,数据库SQL要用到递归查询,这也是我第一次接触SQL的递归查询. 先说一下什么是递归查询,简单说来是将一个树状结构存储在一张表里,比如一个表中 ...

  6. MySQL - Linux下安装

    本安装方式仅对5.7.21版本负责. 下载地址:wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.21-linux-glibc2 ...

  7. Servlet学习笔记04——什么是重定向,servlet生命周期?

    1.重定向 (1)什么是重定向? 服务器通知浏览器访问一个新的地址. 注: 服务器可以通过发送一个302状态码及一个 Location消息头(该消息头的值是一个地址,一般 称之为重定向地址)给浏览器, ...

  8. 柱状图多系列php动态实现(ec)

    <?php require_once 'data.php'; $arr1=$a->sum('answer','ask_id=1'); $arr2=$a->sum('answer',' ...

  9. 深入理解PHP数组函数和预定义接口

    一. PHP对数组的过滤 函数: array_filter(p1[,p2]) 参数p1是要过滤的数组,参数p2是自定义过滤会掉函数(可以是匿名函数) 例子: <?php $arr = ['',n ...

  10. python爬虫:爬取猫眼TOP100榜的100部高分经典电影

    1.问题描述: 爬取猫眼TOP100榜的100部高分经典电影,并将数据存储到CSV文件中 2.思路分析: (1)目标网址:http://maoyan.com/board/4 (2)代码结构: (3) ...