0
点赞
收藏
分享

微信扫一扫

图灵课堂 第五期 JAVA互联网架构师专题/分布式/高并发/微服务 第5期 笔记汇总 并发编程之深入理解JMM&并发三大特性


JMM的内存可见性保证

按程序类型,Java程序的内存可见性保证可以分为下列3类:

单线程程序。单线程程序不会出现内存可见性问题。编译器、runtime和处理器会共同确保单线

程程序的执行结果与该程序在顺序一致性模型中的执行结果相同。

正确同步的多线程程序。正确同步的多线程程序的执行将具有顺序一致性(程序的执行结果与该

程序在顺序一致性内存模型中的执行结果相同)。这是JMM关注的重点,JMM通过限制编译器和处

理器的重排序来为程序员提供内存可见性保证。

未同步/未正确同步的多线程程序。JMM为它们提供了最小安全性保障:线程执行时读取到的

值,要么是之前某个线程写入的值,要么是默认值。未同步程序在JMM中执行时,整体上是无序

的,其执行结果无法预知。 JMM不保证未同步程序的执行结果与该程序在顺序一致性模型中的执行

结果一致。

未同步程序在JMM中的执行时,整体上是无序的,其执行结果无法预知。未同步程序在两个模型中的

执行特性有如下几个差异。

1)顺序一致性模型保证单线程内的操作会按程序的顺序执行,而JMM不保证单线程内的操作会按程序

的顺序执行,比如正确同步的多线程程序在临界区内的重排序。

2)顺序一致性模型保证所有线程只能看到一致的操作执行顺序,而JMM不保证所有线程能看到一致的

操作执行顺序。

3)顺序一致性模型保证对所有的内存读/写操作都具有原子性,而JMM不保证对64位的long型和

链接:​​download​​

提取码:wit3

失效+\/❤:cowcow2100


图灵课堂 第五期 JAVA互联网架构师专题/分布式/高并发/微服务 第5期 笔记汇总 并发编程之深入理解JMM&并发三大特性_并发编程

图灵课堂 第五期 JAVA互联网架构师专题/分布式/高并发/微服务 第5期 笔记汇总 并发编程之深入理解JMM&并发三大特性_内存屏障_02

图灵课堂 第五期 JAVA互联网架构师专题/分布式/高并发/微服务 第5期 笔记汇总 并发编程之深入理解JMM&并发三大特性_并发编程_03图灵课堂 第五期 JAVA互联网架构师专题/分布式/高并发/微服务 第5期 笔记汇总 并发编程之深入理解JMM&并发三大特性_单线程_04


package com.tuling.jucdemo.jmm;


import java.util.concurrent.locks.LockSupport;

import com.tuling.jucdemo.factory.UnsafeFactory;

/**
* @author Fox
*
* -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp
* hsdis-amd64.dll
* 可见性案例
*/
public class VisibilityTest {
// storeLoad JVM内存屏障 ----> (汇编层面指令) lock; addl $0,0(%%rsp)
// lock前缀指令不是内存屏障的指令,但是有内存屏障的效果 缓存失效
private volatile boolean flag = true;
private Integer count = 0;

public void refresh() {
flag = false;
System.out.println(Thread.currentThread().getName() + "修改flag:"+flag);
}

public void load() {
System.out.println(Thread.currentThread().getName() + "开始执行.....");
while (flag) {
//TODO 业务逻辑
count++;
//JMM模型 内存模型: 线程间通信有关 共享内存模型
//没有跳出循环 可见性的问题
//能够跳出循环 内存屏障
//UnsafeFactory.getUnsafe().storeFence();
//能够跳出循环 ? 释放时间片,上下文切换 加载上下文:flag=true
//Thread.yield();
//能够跳出循环 内存屏障
//System.out.println(count);

//LockSupport.unpark(Thread.currentThread());

//shortWait(1000000); //1ms
//shortWait(1000);

// try {
// Thread.sleep(1); //内存屏障
// } catch (InterruptedException e) {
// e.printStackTrace();
// }

//总结: Java中可见性如何保证? 方式归类有两种:
//1. jvm层面 storeLoad内存屏障 ===> x86 lock替代了mfence
// 2. 上下文切换 Thread.yield();


}
System.out.println(Thread.currentThread().getName() + "跳出循环: count=" + count);
}

public static void main(String[] args) throws InterruptedException {
VisibilityTest test = new VisibilityTest();

// 线程threadA模拟数据加载场景
Thread threadA = new Thread(() -> test.load(), "threadA");
threadA.start();

// 让threadA执行一会儿
Thread.sleep(1000);
// 线程threadB通过flag控制threadA的执行时间
Thread threadB = new Thread(() -> test.refresh(), "threadB");
threadB.start();

}


public static void shortWait(long interval) {
long start = System.nanoTime();
long end;
do {
end = System.nanoTime();
} while (start + interval >= end);
}
}


部分目录



并发编程专题

【回放】并发编程之深入理解JMM&并发三大特性(一)(10月27日 20:10-22:00)

【回放】并发编程之深入理解JMM&并发三大特性(二)(10月29日 20:10-22:00)

【回放】并发List、Set、ConcurrentHashMap底层原理(10月31日 20:10-22:00)

【回放】Java并发线程池底层原理详解与源码分析(11月3日 20:10-22:00)

【回放】并发编程之深入理解Java线程(11月5日 20:10-22:00)

【回放】并发编程之CAS&Atomic原子操作详解(11月7日 20:10-22:00)

【回放】并发锁机制之深入理解synchronized(一)(11月10日 20:10-22:00)

06

并发编程专题

【回放】并发锁机制之深入理解synchronized(二)(11月12日 20:10-22:00)

【回放】深入理解AQS之独占锁ReentrantLock源码分析(11月14日 20:10-22:00)

【回放】Semaphorer&CountDownLatch详解(11月17日 20:10-22:00)

【回放】深入理解AQS之CyclicBarrie详解(11月19日 20:10-22:00)

【回放】深入理解AQS之ReentrantReadWriteLock实战(11月21日 20:10-22:00)

【回放】阻塞队列BlockingQueue实战及其原理分析一(11月24日 20:10-22:00)

【回放】阻塞队列BlockingQueue实战及其原理分析二(11月26日 20:10-22:00)

【回放】并发编程之ForkJoin工作原理分析(11月28日 20:10-22:00)

【回放】CompletableFuture实战&Disruptor原理剖析(12月1日 20:10-22:00)

【回放】常用并发设计模式精讲(12月3日 20:10-22:00)

07

性能调优/MySQL

【录播】深入理解Mysql索引底层数据结构与算法(126分钟)

【录播】Explain详解与索引最佳实践(142分钟)

【录播】SQL底层执行原理详解(118分钟)

【录播】Mysql索引优化实战一(150分钟)

【录播】Mysql索引优化实战二(130分钟)

【录播】深入理解Mysql事务隔离级别与锁机制(149分钟)

【录播】深入理解MVCC与BufferPool缓存机制(132分钟)

【回放】高性能业务表结构设计和索引知识深化(12月12日 20:10-22:00)

举报

相关推荐

0 条评论