-
简述Java内存模型
java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量(指实例字段,静态字段,构成数组对象的元素,但不包括局部变量与方法参数,因为是线程私有的)。
Java内存模型规定了所有的变量都存储在主内存中,每一条线程都有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有都必须在工作内存中进行,而不能直接写在主内存中的变量。
不同的线程之间也无法直接访问对方的工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。
-
内存间交互操作(p365)
即一个变量如何主内存拷贝到工作内存,如何从工作内存同步回主存内存之类的实现细节。
8种操作:lock(锁定),unlock(解锁),read(读取),load(载入),use(使用),assign(赋值),store(存储),write(写入)
如果要把一个变量从主内存拷贝到工作内存,需要顺序执行read和load操作,如果要把一个变量从工作内存同步回主内存,需要顺序地执行store和write
3.关键字volatile(p366)
4.long和double型变量的特殊规则(p372)【非原子协定】
java内存模型对8种操作都具有原子性,但是对64位的数据类型,允许虚拟机将没有被volatile修饰的64位数据的读写操作划分为两次32位操作进行,这点就是long和double的非原子性协定。目前各种平台下的商用虚拟机几乎都选择把64位数据的读写操作作为原子操作来对待。
-
简述Java内存模型哪些操作实现原子性、可见性和有序性 (p373)
Java内存模型直接保证原子性变量的操作:read load assign use store write synchronize
可见性:volatile synchronize final
有序性:volatile synchronize
6 简述先行发生原则(p375)
它是判断数据是否存在竞争,线程是否安全的主要依据
7 简述线程实现的三种方式,内核线程、用户线程、用户线程加轻量级进程混合实现(p378)
内核线程:就是直接由操作系统内核支持的线程,这种线程由内核来切换,通过调度器对线程进行调度,每一个内核线程都可以看成是内核的一个分身。程序一般不会直接去使用内核线程,而是使用内核线程的一个高级接口---轻量级线程,轻量级线程就是我们通常意义上所讲的线程。
用户线程:广义上,一个线程如果不是内核线程,就可以看成是用户线程。狭义上是指完全建立在用户空间的线程库上,用户线程的建立、同步、销毁和调度完全建立在用户态中,不需要内核的帮助。
用户线程加轻量级进程混合实现:
8 Java线程的实现(p381)
在目前的JDK版本中,操作系统支持怎么样线程模型,在很大程度上决定了Java虚拟机的线程是怎么样映射的。
9 Java线程调度(p381)
线程调度:指系统为线程分配处理器使用权的过程。主要的方式有协同式线程调度和抢占式线程调度。
协同:线程的执行时间由线程自己控制,线程把自己的工作执行完成之后,要主动通知系统切换线程。
抢占:每个线程将由系统来分配执行时间,线程的切换不是由线程本身决定。
10 简述Java线程的转态转换(p383)
11 synchronized关键字和volatile关键字比较
volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。
多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞
volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。
volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。