Java并发编程之可见性

Java并发编程之可见性

  • 什么是可见性
  • 可见性产生的原因
  • 保证可见性的几种方式
  • 总结

什么是可见性

一个共享变量,T1线程修改他的值,T2线程随后读取到的还是旧值,这就是可见性问题

public class Demo1Visibility {
    int i = 0;
    boolean isRunning = true;

    public static void main(String args[]) throws InterruptedException {
        Demo1Visibility demo = new Demo1Visibility();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("here i am...");
                while(demo.isRunning){
                        demo.i++;
                }
                System.out.println(demo.i);
            }
        }).start();

        Thread.sleep(3000L);
        demo.isRunning = false;
        System.out.println("shutdown...");
    }
}

输出结果

here i am...
shutdown...

主线程对isRunning 的值做了修改,子线程没有读到,没有输出共享变量i的值。

 

可见性产生的原因

导致可见性的原因是cpu缓存,由于主线程对共享变量的修改,子线程没有立马读到修改后的值。

硬件知识:cpu访问速度远远高于内存访问速度,所以在cpu和内存之间有了一层cpu缓存,用来节省cpu的性能消耗。

多线程对共享变量的操作过程:

主线程发起修改共享变量--->写入主线程对应的高速缓存--->写入主内存(修改共享变量的值)---->写入子线程对应的高速缓存--->子线程读取到修改后的共享变量,如下图

 

Java并发编程之可见性_第1张图片

 

保证可见性的几种方式

1.final

初始化字段为final

final boolean isRunning = true;

2.volatile

读写volatile确保可见性

volatile boolean isRunning = true;

2.1.1保证可见性,不保证原子性,一个线程对共享变量修改,其他线程可以马上看到共享变量的最新值

2.1.2.禁止进行指令重排序

3.synchronized
同步块内读写字段确保可见性

synchronized (this){
    demo.i++;
}

 

总结

所有线程间操作,都存在可见性,JAVA内存模型(JMM)需要对其进行规范,实现者为JVM。

本文简单的介绍了可见性产生的原因,列出了处理可见性的几种手段。

你可能感兴趣的:(班级作业)