1.JAVA内存模型
简单的讲,Java 内存模型将内存分为共享内存和本地内存。共享内存又称为堆内存,指的就是线程之间共享的内存,包含所有的实例域、静态域和数组元素。每个线程都有一个私有的,只对自己可见的内存,称之为本地内存。
共享内存中共享变量虽然由所有的线程共享,但是为了提高效率,线程并不直接使用这些变量,每个线程都会在自己的本地内存中存储一个共享内存的副本,使用这个副本参与运算。由于这个副本的参与,导致了线程之间对共享内存的读写存在可见性问题。
2.volatile
一个线程对 volatile 变量的读一定能看见在它之前最后一个线程对这个变量的写。
为了实现这些语义,Java 规定,(1)当一个线程要使用共享内存中的 volatile 变量时,如图中的变量a,它会直接从主内存中读取,而不使用自己本地内存中的副本。(2)当一个线程对一个 volatile 变量进行写时,它会将这个共享变量的值刷新到共享内存中。
我们可以看到,其实 volatile 变量保证的是一个线程对它的写会立即刷新到主内存中,并置其它线程的副本为无效,它并不保证对 volatile 变量的操作都是具有原子性的。
3.Synchronized
1.线程加锁的时候,先清空工作内存中的变量,因此使用变量时,需要从主内存中重新读取最新的值
2.线程解锁时,把线程独有的工作内存中的变量刷新到主内存中
4.volatile 和 synchronized比较
根据以上的分析,我们可以发现volatile和synchronized有些相似。
当线程对 volatile变量写时,java 会把值刷新到共享内存中;而对于synchronized,指的是当线程释放锁的时候,会将共享变量的值刷新到主内存中。
线程读取volatile变量时,会将本地内存中的共享变量置为无效;对于synchronized来说,当线程获取锁时,会将当前线程本地内存中的共享变量置为无效。
synchronized 扩大了可见影响的范围,扩大到了synchronized作用的代码块。
5.final 变量
final关键字可以作用于变量、方法和类,我们这里只看final 变量。final变量的特殊之处在于,final 变量一经初始化,就不能改变其值。
这里的值对于一个对象或者数组来说指的是这个对象或者数组的引用地址。因此,一个线程定义了一个final变量之后,其他任意线程都拿到这个变量。但有一点需要注意的是,当这个final变量为对象或者数组时,
1.虽然我们不能讲这个变量赋值为其他对象或者数组,但是我们可以改变对象的域或者数组中的元素。
2.线程对这个对象变量的域或者数据的元素的改变不具有线程可见性。
网友评论