对象共享
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. 浏览器及Windows常用快捷键汇总

    浏览器常用快捷键: F5 刷新 Ctrl+N 打开新窗口 Ctrl+T 打开新标签 Ctrl +  O  打开浏览器的时候打开文件 Ctrl+Shift+N 隐身模式打开窗口 F2 F3 切换  Ct ...

  2. 一分钟了解Docker

    一.Docker概述 Docker和虚拟机一样,都拥有环境隔离的能力,但它比虚拟机更加轻量级,可以使资源更大化地得到应用. Docker用途:简单配置.代码流水线管理.开发效率.应用隔离.服务器整合. ...

  3. ASP.NET Core SignalR:基础概述

    一.简介 ASP.NET Core SignalR 是一个开源代码库,它简化了向应用添加实时 Web 功能的过程. 实时 Web 功能使服务器端代码能够即时将内容推送到客户端. SignalR 的适用 ...

  4. ASP.NET Core 2.2 WebApi 系列【二】使用EF CodeFirst创建数据库

    Code First模式 Code First是指"代码优先"或"代码先行". Code First模式将会基于编写的类和配置,自动创建模型和数据库. 一.准备 ...

  5. GO-逻辑判断(if,else if,else,switch)

    一.if逻辑判断 package main import "fmt" func main() { var a =10; if a>10 { //大括号前不能回车 fmt.Pr ...

  6. 松软科技带你学开发:SQL--COUNT() 函数

    SQL COUNT() 语法 SQL COUNT(column_name) 语法 COUNT(column_name) 函数返回指定列的值的数目(NULL 不计入): SELECT COUNT(col ...

  7. Python 实现 Hangman 小游戏

    Hangman--游戏简介--> 百度百科 打印Hangman def printHangman(N): # 第一行 print("\t____") # 第二行 print( ...

  8. Educational Codeforces Round 74 (Rated for Div. 2)

    传送门 A. Prime Subtraction 判断一下是否相差为\(1\)即可. B. Kill 'Em All 随便搞搞. C. Standard Free2play 题意: 现在有一个高度为\ ...

  9. vue中is的使用

    :is作用 1.动态切换不同组件 <div id="app"> <button @click="changeComponent('component1' ...

  10. matlab练习程序(图像投影到点云)

    最近接触点云比较多,如果把图像投影到点云应该挺有意思. 首先需要载入图像,然后做个球或其他什么形状的点云,这里可以参考球坐标公式. 最后通过pcshow将像素输出到点云上即可. 原图: 投影后的点云: ...