并发编程之深入理解JMM&并发三大特性

1.并发和并行区别:

共同的目标:最大化CPU的使用率

并行:指同一时刻,有多条指令在多个处理器上同时执行,(个人理解只有多个处理器才会出现并行)

并发:指同一时刻只能有一条指令执行,只是把时间分成若干段,使多个进程交替的执行

并发解决的问题:多线程中的同步,互斥,分工等问题。

2.并发的三大特性:

1> 可见性:当一个线程修改了共享变量的值,其他线程能够看到修改的值;

public class VisibilityTest {

    private boolean flag = true;

    public void refresh() {
        flag = false;
        System.out.println(Thread.currentThread().getName() + "修改flag");
    }
    public void load(){
        System.out.println(Thread.currentThread().getName()+"开始执行");
        int i = 0;
        while (flag){
            i++;

        }
        System.out.println(Thread.currentThread().getName()+"跳出循环: i = "+ i);
    }

    public static void main(String[] args) throws InterruptedException {
        VisibilityTest test = new VisibilityTest();
        Thread threadA = new Thread(()->test.load(),"threadA");
        threadA.start();
        Thread.sleep(1000);
        Thread threadB = new Thread(()->test.refresh(),"threadB");
        threadB.start();
    }
  
}

上面的代码,不会跳出循环,出现了可见性的问题:

并发编程之深入理解JMM&并发三大特性_第1张图片

 由上图可见导致可见性问题的原因是A线程里没有刷新flag的值

解决可见性的方法

通过 volatile 关键字保证可见性;
通过 内存屏障保证可见性;
通过 synchronized 关键字保证可见性;
通过 Lock保证可见性;
通过 final 关键字保证可见性

 

并发编程之深入理解JMM&并发三大特性_第2张图片

 并发编程之深入理解JMM&并发三大特性_第3张图片

LOCK 前缀指令会 等待它之前所有的指令完成、并且所有缓冲的写操作写回内存 (也就是
将store buffer中的内容写入内存)之后才开始执行,并且根据缓存一致性协议, 刷新
store buffer的操作会导致其他cache中的副本失效

保证可见性的方法:内存屏障,上下文切换

你可能感兴趣的:(java,多线程)