1.2.1线程安全之可见性问题

1.多线程中的问题

(1)所见非所得
(2)无法肉眼去检测程序的准确性
(3)不同的运行平台有不同的表现
(4)错误很难重现

2.问题

(1)从内存结构到内存模型

【高性程】1.2.1线程安全之可见性问题

(2)工作内存缓存

【高性程】1.2.1线程安全之可见性问题

(3)指令重排序

Java编程语言的语义允许编译器和微处理器执行优化,这些优化可以与不正确的同步代码交互,从而产生看似矛盾的行为。(不仅仅是Java级别,也是CPU级别;
内存屏障,不仅会调用jit,还会调用CPU的指令禁止重排序)

3.内存模型的含义

内存模型描述程序的可能行为。
【高性程】1.2.1线程安全之可见性问题
【内存模型决定了线程在程序的每个点上可以读取什么值。】

4.Shared Variables共享变量描述

【高性程】1.2.1线程安全之可见性问题

5.线程操作的定义

【高性程】1.2.1线程安全之可见性问题
程序顺序:如果一个程序没有数据竞争,那么程序的所有执行看起来都是顺序一致的。
本规范只涉及到线程间(多线程)的操作。

6.对同步的规则定义(定义了读数据)

【高性程】1.2.1线程安全之可见性问题

7.happens-before先行发生原则

【高性程】1.2.1线程安全之可见性问题
当程序包含两个没有被happens-before关系排序的冲突访问时,就称存在【数据争用】。
遵守了这个原则,也就意味着有些代码不能进行重排序,有些数据不能缓存。

8.volatile关键字

【高性程】1.2.1线程安全之可见性问题

9.final在jvm中的处理

【高性程】1.2.1线程安全之可见性问题

10.Word Tearing字节处理

【高性程】1.2.1线程安全之可见性问题

11.double 和long的特殊处理

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

1.2.2线程安全概念之原子操作

编译反编译查看class内容的命令 :java -p -v 名称
【高性程】1.2.1线程安全之可见性问题

1.原子操作定义

【高性程】1.2.1线程安全之可见性问题
【示例】
【高性程】1.2.1线程安全之可见性问题
存在竞态条件线程不安全,需要转变为原子操作才能安全。方式:循环CAS、锁。

2.CAS机制

底层提供,针对变量级别,某一个属性或者某一个内存地址的操作。
实际应用中,不需要这么麻烦。因为Java为我们提供了一个J.U.C包内原子操作封装类。
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
三个问题
【高性程】1.2.1线程安全之可见性问题

3.J.U.C包内原子操作封装类。

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

1.2.3锁的概念和synchronized关键字

1.Java中锁的概念

【高性程】1.2.1线程安全之可见性问题
几种重要的锁实现方式:synchronized、 ReentrantLock、 ReentrantReadWriteLock

2.同步关键字synchronized

(1)概念

Java中每个对象都会有一个与之对应的监视器(object–mointor)
【高性程】1.2.1线程安全之可见性问题
锁消除:如果没有什么竞争,就不应该用锁。
锁粗化:如果存在多个小范围的锁,可以变成一个大的锁。
同步关键字,不仅是实现同步,根据JVM规定还能保证可见性(读取最新主内存数据,结束后写入主内存)

(2)同步关键字加锁原理

【高性程】1.2.1线程安全之可见性问题

3.偏向锁到轻量级锁

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

4.重量级锁-监视器(monitor)

修改mark word如果失败,会自旋CAS一定次数,该次数可以通过参数配置:
超过次数,仍未抢到锁,则锁升级为重量级锁,进入阻塞。
monitor也叫做管程,计算机系统原理中有提及类似的概念。一个对象会有一个对应的monitor。
【高性程】1.2.1线程安全之可见性问题

1.2.4Lock锁接口实现

1.Lock的核心API

【高性程】1.2.1线程安全之可见性问题
根据Lock的源码注释,Lock接口的实现,具备和同步关键字同样的内语义。

2.RenentrantLock

独享锁;支持公平锁、非公平锁两种模式;可重入锁;
重入的时候,加锁和解锁的次数要一致;有多少次lock就需要有多少次unlock。
【高性程】1.2.1线程安全之可见性问题

3.ReadWriteLock

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

4.Condition

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
源码示例:
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
synchronized要了解
lock 要学会使用

1.3.1AQS抽象队列同步器详解

1.同步锁的本质-排队

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
自己实现(独享锁)
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

2.AQS抽象队列同步器

AQS!=Lock,但是可以实现Lock。(AQS大量用到了CAS)
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
通过对比源码,发现可以将上面自己写的独享锁封装起来
写个AQS-独享锁
(模板方法,设计好骨架,具体实现由子类来完成)
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
独享锁 实现抽象的AQS的方法
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

3.资源占用流程

【高性程】1.2.1线程安全之可见性问题
信号量和栅栏和倒计数器

4.Sempaphore

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
写个AQS-共享锁
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
信号量
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

4.CountDowmLatch

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

5.CyclicBarrier

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
示例:
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

1.3.2并发容器类Map-J.U.C并发编程包详解

1.实现hashMap分析

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
以上为jdk1.7里的内容,1.8版本没有segments(分段锁,相当于固定的锁,不能扩容 ),通过CAS机制。下图:
【高性程】1.2.1线程安全之可见性问题

2 .ConcurrentSkipListMap

【高性程】1.2.1线程安全之可见性问题

3.使用链表存储

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

1.3.3并发容器类list_set_queue

1.List

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

2.Set集合

【高性程】1.2.1线程安全之可见性问题

3.Queue API

【高性程】1.2.1线程安全之可见性问题

1.3.4Fork_Join框架详解

1.Fork_Join作用

【高性程】1.2.1线程安全之可见性问题

2. 意图梳理【高性程】1.2.1线程安全之可见性问题

3.应用场景,查询多个系统数据

优惠券等经常变动的消息,在一个系统中。用户基本信息等,在另一个系统。
【高性程】1.2.1线程安全之可见性问题

4.代码示例

【高性程】1.2.1线程安全之可见性问题

(1)调用接口,耗时→用多线程改造

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
ForkJoin工作窃取:每个线程有一个属于自己的队列,当自己的队列没有任务的时候,会窃取有任务的队列,帮助 它执行任务。
冲突低;
【高性程】1.2.1线程安全之可见性问题
实现思路
【高性程】1.2.1线程安全之可见性问题

(2)使用场景

定义一个fork join pool
线程数量和CPU核数差不多
非阻塞处理non blocking
纯内存操作、数据计算
【高性程】1.2.1线程安全之可见性问题

(3)用countDowmLatch改造

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【FutureTask原理及多线程知识扩展】

1.Future

【高性程】1.2.1线程安全之可见性问题

2.FutureTask应用

【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
代码执行:
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
futureTask实现步骤:
call方法运行在run()方法里面
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题
【高性程】1.2.1线程安全之可见性问题

3.线程安全性级别

【高性程】1.2.1线程安全之可见性问题

相关文章: