1. 解决面试过程中常见的线程原理问题
2. 帮助大家在工作中更好的利用多线程
3. 建立完整的并发编程领域的知识体系
4. 规避在开发中线程使用不合理带来的线程安全问题
你将收获
1. 解决面试过程中常见的线程原理问题
2. 帮助大家在工作中更好的利用多线程
3. 建立完整的并发编程领域的知识体系
4. 规避在开发中线程使用不合理带来的线程安全问题
适用人群
课程介绍
同学笔记
2021-01-22 15:26:54
1、死锁条件
(1)互斥
(2)占有且等待
(3)不可抢占
(4)循环等待
2、Thread.join=》是Happens-Before的一种规则
如果我们期望线程内的数据操作,对线程外的操作可见,可以通过join来做
join阻塞的是主线程(通过wait),子线程执行结束后,唤醒主线程,这时候,主线程就可以读到子线程中对共享变量修改后的最新值
3、ThreadLocal->线程级别的数据隔离,在线程里面是数据隔离的
2021-01-22 10:17:37
来源:探索线程安全性背后的本质之volatile 02 查看详情
1、如何才能 CPU层面的优化失效来解决可见性问题和指令重排序问题呢?
那就是实时让缓存失效,从内存中读取数据=》也就是搞一下 内存屏障
内存屏障作用就是 不允许指令重排序,禁用高速缓存
加入volatile关键字,就会增加这个内存屏障
2、java内存模型(JMM) 定义了共享内存中,多线程读写的规范,解决了不同平台的差异化,提供一个统一的线程安全性的一致性模型,提供了可见性和有序性问题的解决方案
3、开发的指令到执行的指令会经过三步优化
源代码=》编译器优化重排序=》(CPU层面)指令级并行重排序=》(CPU层面)内存系统重排序=》最终执行指令排序
这些优化就会造成可见性问题,所以硬件层面就又提供了内存屏障来解决这个问题,软件层面提供了调用内存屏障的方法
4、综上 volatile是如何解决可见性问题的呢?
提供了一个防止内存指令重排序的机制和通过内存屏障机制去解决可见性问题
5、那么volatile在什么情况下使用呢?
存在多个线程访问、并发访问的可能性,那么需要加volatile来保证可见性
6、引申问题 单例模式中 双重检查锁判断 instance==null
A a;
a=new A();
new A() 在操作系统中 是三个指令 会有重排序问题 所以 需要加 volatile关键字
static volatile A a;
a=new A();
7、Happens-Before模型-软件层面的一种自身解决可见性问题的模型
A Happens Before B,并不是A一定运行在B之前,而是 A的结果值对B可见
什么情况下会存在这个模型?
(1)程序顺序规则(as-if-serial)
不能改变程序的执行结果(单线程环境下,执行结果不变)
依赖问题,如果两个指令存在依赖关系,不允许重排序
int a=0;int b=1; int c=a*b;
(2)传递性规则
A Happens Before B;
B Happens Before C;
A的结果一定对C可见
(3)volatile变量规则
volatile修饰变量的写操作,一定hanppens-before 后续对vaolatile变量的读操作,因为内存屏障机制来防止指令重排序
(4)监视器锁规则
一个锁的释放操作,一定hanppens-before 后续其他线程对应锁的操作 其实就是synchronized();本身加锁,所以在所有线程中是可见的,不可重排序的
(5)start规则
int x=10;
Thread t1=new Thread(()->{读取 x值,一定是20});
x=20;
t1.start();
start之前的操作一定 hapens-before 线程中的任意操作
(6) join规则
Thread.join();是一种阻塞行为
没有更多了
课程讨论
暂无评论