深入理解Java虚拟机之(2)Java内存模型与线程 个人总结

一、把我能想到的写下来:

1.CPU的内存模型:

     工作内存是各个CPU共享的一个区域,像堆、方法区都在这里,而程序计数器、线程私有的都是在CPU各自的工作内存中的,主内存是处理数据的地方。
深入理解Java虚拟机之(2)Java内存模型与线程 个人总结

2.Java内存模型:

 当线程对变量进行写入操作时,先会把值写入该线程的一级缓存中,然后再刷新到二级缓存中,而读取值是先到自己的一级缓存中进行读取,如果没有找到该变量,才去二级缓存中。
深入理解Java虚拟机之(2)Java内存模型与线程 个人总结
内存可见性:线程A对共享变量 r 的修改(更新),对于其他线程都是可见的。 ???
这两个内存模型有什么关系???

3. 8 个原子性操作:

深入理解Java虚拟机之(2)Java内存模型与线程 个人总结
lock:只有拥有监视器锁的线程才可以对主内存进行操作。???
unlock:释放监视器锁,将计数器值置为 0 。
assign:每个字节码指令都是由操作数和操作动作???构成的。assign 会取操作数,然后交给执行引擎,进行赋值。
store:存入工作线程。
     在 write 之前一定有 load 操作,先写入 工作线程,再写入主线程中;
     在 read 之前按一定有 use 操作。

4.volitile变量。

     volatile 用在共享变量前,可以避免指令重排序,(虚拟机有指令优化机制,在不影响执行结果的情况下会进行指令重排 ??? )它的语义:在读取变量之后的命令不能排在读取前面;在写变量之前的命令不能排在写后面。
能保证内存可见性,但不能保证同步/线程安全。因为内存可见性是对于变量来说,该变量的读 与 写 操作受影响,而Java并不是每条语句都是是原子性的。比如:
volatile修饰的变量 i 初值为 0,进行自增操作 i++ ,这一条Java 语句,用javac 编译,通过查看 class 文件??? 它的是有 3 句指令的:
(1)读取 i 的值 。
(2)求 i +1 的值
(3)将 i+1 的值赋给 i。
比如线程 A 先执行(1),进行 读 的操作,是直接从主内存中取值,这时 i=0,接下来切换到线程 B ,线程 B 先执行 (1),进行 读 的操作,从主内存中取值,i=0,然后执行(2),i+1的值为 1,接下来执行(3),会将1直接刷新到主内存中,不会存在任何缓存中。切换到线程 A 中,这时已经执行过(1)读取操作了,该执行(2)了,I+1的值仍为 1 ,接下来执行(3),会将 1 刷新到主内存中,而经过这俩线程,自增操作的结果 是 ”1“,而不是预期中的 2。
     除了 volatile 可以保证内存可见性,synchronized、final也可以。
     

5.先行性原则

     如果A对B具有先行性,说明发生在 B 之前的 A 的更新操作,B是可见的。以下情况是满足先行性原则的:
(1)synchronized修饰的同步块和同步方法。
(2)volitale
(3)CAS操作
(4)???
     

6.原子性操作

原子性是指语句整体是一起执行的,不能有部分没有被执行。 ???
     

7.线程的 5 种状态

(1)new ,使用 new 创建对象线程后。
(2)runnable,一start() ,线程就进入就绪状态,准备好了除 CPU 时间片以外的资源。
(3)等待分为untimed wait 不限时等待 和 timed wait 限时等待。
(4)blocked,线程被阻塞,当要进入同步块,但未持有资源对象的监视器锁时。
(5)terminal:终止,线程的run() 方法正常结束而退出或遇到异常。
状态转换图:
深入理解Java虚拟机之(2)Java内存模型与线程 个人总结

二、补充