对象共享
synchronized 设定原子性确定临界区 + 内存可见性
要解决如下问题
防止一个线程在使用对象状态而另一个线程在修改对象状态;且当一个线程修改了对象状态后,对其他线程可见。
 
可见性
多线程情况下的读写,无法保证在执行读操作时能够看到其他线程写入的值 --- 同步机制解决
造成可见性的原因之一:指令重排序 ---- 产生失效数据
 
在32为机器执行double和long的问题
Jvm会拆分为两个32为的操作,在读取或写入时可能存在问题
读取到某个数的的高32位和另一个数的低32位     ---- (volatile)
 
加锁和可见性
加锁不仅是局限于互斥行为,还包括内存可见性。所有执行读写操作的线程都必须在同一个锁上同步。(happen-before)
 
volatile
保证变量更新通知其他线程,volatile变量确定为共享变量,不会进行指令重排序。而且不会被寄存器缓存。
volatile可见性,A线程写入一个volatile变量,B线程读取该变量。在写入之前对A可见的所有变量的值,在B读取变量以后对B也可见。
使用情况:在需要对可见性进行复杂判断时,不适用;适用于:自身状态可见性,确保引用状态的可见性,标识一些重要的程序生命周期事件的发生(init/destroy)
volatile不能保证递增操作的原子性。
加锁操作即可保证原子性又能保证可见性,volatile只能保证可见性
 
volatile使用总结
对变量的写入操作不依赖于变量当前值,或者确保单线程更新变量
该变量不会与其他状态变量一起纳入不变性条件中
(不变性条件:
对象创建以后其状态就不能修改
对象的所有域都是final类型
对象是正确创建的(在对象的创建期间,this引用没有溢出)
)
在访问变量时不需要加锁
 
发布与逸出
发布:对象能在当前作用域以外的地方使用
逸出:对象在不该被发布时发布了(如对象构建完成前)
不要在构造其中使用this引用逸出。
 
线程封闭
不使用共享数据 --- 线程封闭
单线程内访问数据
当某个对象封闭在一个线程中时,将自动实现线程安全,即使被封闭的对象本身不是线程安全的
(JDBC -- Connection,局部变量,ThreadLoacal)
 
Ad-hoc线程封闭
维护线程封闭完全由程序承担。,访问volatile变量时如可以保证时单线程写入,则可以实现特殊的线程封闭,且volatile可保证可见性,其他线程可以看到最新值
 
栈封闭
局部变量
 
不变性
不可变对象一定线程安全
 
final域
构造不可变对象
保证对象初始化过程的安全性,共享final对象时无需同步。
如果final类型域指向的是可变的对象,在访问这些域所指向对象的状态时仍然需要同步
 
安全的发布模式
在静态初始化函数中初始化一个对象引用。
将对象引用保存在volatile类型的域或者AtomicReferance对象中
将对象引用保存到某个正确构造对象的final类型域中
将对象引用保存到一个由锁保护的域中
保证安全发布的容器
Vector / synchronizedList
Hashtable / synchronizedMap / ConcurrentMap
CopyOnWriteArrayList / CopyOnWriteArraySet / synchronizedSet
BlockingQueue / ConcurrentLinkedQueue
其他数据传输机制:Future / Exchanger
 
事实不可变对象
发布以后的状态不会再改变状态的对象
 
对象的发布需求取决于可变性:
不可变对象可以任意的发布
事实不可变对象需要安全的发布
可变对象需要安全的发布,并且线程安全必须用某个锁保护起来
 
并发程序中使用共享对象的常用策略
线程封闭 --- 对象只有一个线程持有
只读共享 --- 可变对象/不可变对象的多线程读取
线程安全共享 --- 在线程安全内部实现同步
保护对象 --- 加锁

Java并发编程杂记(2)的更多相关文章

  1. Java并发编程杂记(1)

    高并发: cpu -- 缓存 -- 内存 资源利用率 公平性 便利性   生活举例 --- 串行任务中的异步性:我在烧水的时候看书 --- 平衡点   安全性问题 --- 产生竞态条件 共享数据 -- ...

  2. 【Java并发编程实战】----- AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...

  3. 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

    在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...

  4. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  5. 【Java并发编程实战】-----“J.U.C”:CLH队列锁

    在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...

  6. 【Java并发编程实战】-----“J.U.C”:CountDownlatch

    上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...

  7. 【Java并发编程实战】-----“J.U.C”:CyclicBarrier

    在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...

  8. 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock

    ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...

  9. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

随机推荐

  1. sprintf函数 (字符格式化函数)

    sprintf函数 字符串格式化命令,主要功能是把格式化的数据写入某个字符串中. sprintf函数原型在<studio.h>中. sprintf( [指向输入格式化后的字符串的缓冲区的指 ...

  2. Java 后台请求第三方系统接口详解

    //调用第三方系统接口 PrintWriter out = null; BufferedReader in = null; JSONObject jsonObject = null; Closeabl ...

  3. Python 从入门到进阶之路(六)

    之前的文章我们简单介绍了一下 Python 的面向对象,本篇文章我们来看一下 Python 中异常处理. 我们在写程序时,有可能会出现程序报错,但是我们想绕过这个错误执行操作.即使我们的程序写的没问题 ...

  4. Spring Cloud(一):入门篇

    Spring Cloud 简介 Spring Cloud 是一个基于 Spring Boot 实现的微服务架构开发工具,可以快速构建分布式系统中的某些常用模式,如配置管理.服务治理.断路器.智能路由. ...

  5. Actor模型(分布式编程)

    Actor的目的是为了解决分布式编程中的一系列问题.所有消息都是异步交付的,因此将消息发送方与接收方分开,正是由于这种分离,导致actor系统具有内在的并发性:可以不受限制地并行执行任何拥有输入消息的 ...

  6. 写了个爬虫代理ip的脚本给大家使用

    写了个爬虫代理ip的脚本给大家使用 一.代码 import requests from lxml.html import etree url = 'http://www.kuaidaili.com/f ...

  7. Netty服务端Channel的创建与初始化

    Netty创建服务端Channel时,从服务端 ServerBootstrap 类的 bind 方法进入,下图是创建服务端Channel的函数调用链.在后续代码中通过反射的方式创建服务端Channel ...

  8. 解决npm下载慢的问题

    方法一:使用淘宝定制的cnpm命令行工具替代默认安装npm npm install -g cnpm --registry=https://registry.npm.taobao.org 方法二:将np ...

  9. SQL Server查询数据库近期执行的SQL语句

    SELECT TOP 1000        ST.text AS '执行的SQL语句',       QS.execution_count AS '执行次数',       QS.total_ela ...

  10. webpack打包 The 'mode' option has not been set, webpack will fallback to

    webpack 打包报错 The 'mode' option has not been set, webpack will fallback to 'production' for,Module no ...