日常小记
1、Java中的volatile 变量是什么
在利用Java编写的程序中,编译器会自动对其进行优化,把经常被访问的变量缓存起来,程序在读取这个变量时有可能会直接从缓存中来读取这个值,而不会从内存中读取。这个操作虽然能提高程序的运行效率,但当遇到多线程编程时,变量的值可能因为别的线程而改变了,而该缓存的值不会相应改变,从而造成程序读取的值和实际的变量值不一致。此时有一个类型修饰符volatile,它是被设计用来修饰被不同线程访问和修改的成员变量。被volatile类型定义的变量,系统每次用到它时都是直接从对应的内存当中提取,而不会利用缓存。值得注意的是,volatile不能保证操作的原子性,并且,它会阻止编译器对代码的优化,降低程序的执行效率,因此,能不用volatile就尽量不用volatile。
2、Java内存模型是什么
Java内存模型规定和指引Java程序在不同的内存架构、CPU和操作系统间有确定性地行为。它在多线程的情况下尤其重要。Java内存模型对一个线程所做的变动能被其它线程可见提供了保证,它们之间是先行发生关系。这个关系定义了一些规则让程序员在并发编程时思路更清晰。比如,先行发生关系确保了:
-
- 线程内的代码能够按先后顺序执行,这被称为程序次序规则。
- 对于同一个锁,一个解锁操作一定要发生在时间上后发生的另一个锁定操作之前,也叫做管程锁定规则。
- 前一个对volatile的写操作在后一个volatile的读操作之前,也叫volatile变量规则。
- 一个线程内的任何操作必需在这个线程的start()调用之后,也叫作线程启动规则。
- 一个线程的所有操作都会在线程终止之前,线程终止规则。
- 一个对象的终结操作必需在这个对象构造完成之后,也叫对象终结规则。
- 可传递性
3、什么是线程安全?Vector是一个线程安全类吗?
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。Vector 是用同步方法来实现线程安全的, 而和它相似的ArrayList不是线程安全的。