对象共享
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. 一、I/O模型之BIO

    I/O模型之BIO 基本介绍 Java BIO 就是传统的 Java IO 编程,其相关的类和接口再 java.io 包下 BIO(blocking I/O):同步阻塞,服务器实现模式为一个连接一个线 ...

  2. C#_.NetFramework_WebAPI项目_EXCEL数据导出

    [推荐阅读我的最新的Core版文章,是最全的介绍:C#_.NetCore_Web项目_EXCEL数据导出] 项目需要引用NPOI的Nuget包: A-2--EXCEL数据导出--WebAPI项目--N ...

  3. 爬虫selenium中截图

    一.整个页面截图 driver = webdriver.Chrome() driver.get(url) diver.save_screenshot('保存路径') 二.局部截图 driver = w ...

  4. JS基础语法---作用域链

    从函数嵌套来分析: (层数一般5层内) var num=10; function f1() { var num=20; function f2() { var num=30; function f3( ...

  5. Web APP自动更新

    我们的手机软件每天都要经营,经常需要更新,比如程序的Bug,好的功能,好的洁面... ... 这就需要我们的用户打开web app时候自动更新客户端程序,而不是再去应用程序商店从新下载.今天的笔记就是 ...

  6. [转载] Java的四种引用关系

    目录 1 强引用 (Final Reference) 2 软引用 (Soft Reference) 2.1 案例1: 软引用的垃圾回收 2.2 案例2: 软引用缓存的使用 2.3 软引用的应用场景 3 ...

  7. Ride to Office

    [题目描述] 起点与终点相隔4500米.现Charley需要从起点骑车到终点.但是,他有个习惯,沿途需要有人陪伴,即以相同的速度,与另外一个人一起骑.而当他遇到以更快的速度骑车的人时,他会以相应的速度 ...

  8. C#&.Net干货分享-构建后台自动定时任务的源码

    1.创建一个自动处理中心任务参数的类,直接源码: namespace Frame.AutoProcess{    /// <summary>    /// 委托(用于异步处理任务)    ...

  9. MSSQL 删除重复数据

    --删除重复数据,无标识列情况 if object_id(N'test',N'U') is not null drop table test go create table test( id INT, ...

  10. 失败的一天(找bug)

    前天早上来到实验室,准备抓紧时间写写代码,毕竟第二天就是组会了.点了一下鼠标,发现显示屏无法唤醒,然后就准备强制关机再开机(我一般不关机,以前遇到过几次无法唤醒),低头发现主机不亮,然后按了开关也不亮 ...