Java多线程学习(一)volatile解析

锁的基本特性是同步、互斥、内存可见。

synchronized内部锁是可重进入的,意思就是当一个线程获得了这个锁,那么它可以调用这个锁中的方法或者变量多次。这样有利于子类在重写了父类的锁方法之后再调用父类的锁方法。因为锁是基于线程的。

Atomic关键字可以保证对修饰变量的操作都是原子的。

锁的获得和释放也是需要开销的,所以不能频繁的获得和释放锁。

长时间的占有锁会引起性能和活跃度的问题。

可见性:可见性是指对于一个线程修改的变量值,其他线程能够及时看到修改后的数据。

指令重排序是因为CPU在执行指令的时候是按照流水线方式的,不同的操作指令在不同的流水线,不同流水线中指令数量不同,所以可能导致顺序流入,乱序流出。

volatile可防止指令的重排序。但是volatile修饰的变量不会加锁,也就不会引起线程的阻塞。而且volatile只能保证可见性,并不能保证原子性。因为volatile修饰的变量不会缓存,所以线程每次读取到的都是某一线程写入的最新值。

原因:JVM内存模型中的虚拟机栈,每个线程运行的时候都有一个自己的线程栈,线程栈中保存了线程的变量信息。当线程要访问对象的变量时,首先会通过存储在栈中的对象的引用去找到存储在堆中的对象信息,然后讲堆中的变量信息拷贝一个副本到线程的本地内存中,之后线程就不再和堆内存中的变量打交道,而是直接堆副本变量进行读写,在操作完成后的某一时刻,自动将线程本地内存中的副本变量同步到堆内存中。volatile的作用就是强制让访问该修饰变量的线程操作堆内存中的变量,不允许线程拷贝副本,所以就保证了任何一个线程访问的都是变量本身,也就保证了可见性。

操作过程:

Java多线程学习(一)volatile解析


变量的种类:

局部变量是指在具体方法中或者for,while中定义的变量。

全局变量也就是成员变量,是指定义在类中的变量。并且分为了static类型的静态类变量和实例变量。静态变量是所有对象共享,各个对象拥有自己的实例变量,存放在对内存中。而方法是共有的,存储在方法区。