多线程之volatile关键字测试
1:测试分析
如上图JMM模型中,我们直到线程有自己的内存空间,而当线程1修改了自己本地的内存空间的变量后,未能及时将变量写回主存,则回导致线程2无法获取最新的变量值,而造成脏读。我们解决的方法就是使用volatile关键字修饰这个变量,使得这个变量有可见性。但是在不使用该变量情况下一定回出现我们说的脏读吗?或者可能出现吗?当前并发编程就是这样的,有时候能模拟出来,有时候模拟不出来。
2:代码验证
我们使用volatile关键字修饰共享变量,然后在两个线程中,分别针对该变量加一操作,观察结果。如果这个变量具有可见性,那么每一个线程之间的加一,会表现出两个线程加一都是互相可见的,结果就是加一会是。如果这个变量不可见性,则每一个线程的加一操作相当于在自己线程的值上加一。
package ConcurrentHashMapTest; /** * @author :dazhu * @date :Created in 2020/4/14 7:55 * @description: * @modified By: * @version: $ */ public class Main { public static void main(String[] args) { Node n0 = new Node(0); new Thread(new Runnable() { @Override public void run() { for(int j=0;j<5000;j++){ n0.i++; // try { // Thread.sleep(1); // } catch (InterruptedException e) { // e.printStackTrace(); // } System.out.println("i="+n0.i+"thread name"+Thread.currentThread().getName()); } } },"t1").start(); new Thread(new Runnable() { @Override public void run() { for(int j=0;j<5000;j++){ n0.i++; // try { // Thread.sleep(1); // } catch (InterruptedException e) { // e.printStackTrace(); // } System.out.println("i="+n0.i+"thread name"+Thread.currentThread().getName()); } } },"t2").start(); } } class Node{ //i变量是否使用volatile修饰 public volatile int i; public Node(int i){ this.i = i; } }
我们从结果来看最后的加的值等于10000说明每一个线程的加一操作对其他线程都是可见的,所以变量是共享的尼。如果我们不适用volatile修饰共享变量,会出现什么结果尼?