Java高并发-Java内存模型和线程安全

Posted okokabcd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java高并发-Java内存模型和线程安全相关的知识,希望对你有一定的参考价值。

一、原子性

原子性是指一个操作是不可中断的。即使在多个线程一起执行的时候,一个操作一旦开始,就不会被其它线程干扰。

i++是原子操作吗?
不是,包含3个操作:读i,i=i+1,写i

32位的机子上读取64位的long型也不是原子操作

二、有序性

2.1 举例

在并发时,程序的执行可能会出现乱序

技术分享图片

2.2 步骤

一条指令的执行是可以分为很多步骤的:

  • 取指IF
  • 译码和取寄存器操作数ID
  • 执行或者有效地址计算EX
  • 存储器访问MEM
  • 写回WB

流水线执行指令

技术分享图片

分析:

指令分解成不同阶段
假设一条指令消耗一个CPU时钟周期
5个人生产一个产品,5个人同时工作

a=b+c
读b
读c
计算b+c,结果放到a
写a

技术分享图片

分析:

进行优化,使气泡尽可能的少

技术分享图片

分析:

调整指令顺序,可以消除气泡

技术分享图片

三、可见性

3.1 定义

可见性是批当一个线程修改了某一个共享变量的值,其他线程是否能够立即知道这个修改。

  • 编译器优化
  • 硬件优化(如写吸收,批操作)
批量操作,把操作进行积累,只把最终结果写入

技术分享图片

3.2 Java虚拟机层面的可见性

http://hushi55.github.io/2015/01/05/volatile-assembly

public class VisibilityTest extends Thread {
    private boolean stop;

    public void run() {
        int i = 0;
        while (!stop) {
            i++;
        }
        System.out.println("finish loop,i=" + i);
    }

    public void stopIt() {
        stop = true;
    }

    public boolean getStop() {
        return stop;
    }

    public static void main(String[] args) throws Exception {
        VisibilityTest v = new VisibilityTest();
        v.start();

        Thread.sleep(1000);
        v.stopIt();
        Thread.sleep(2000);
        System.out.println("finish main");
        System.out.println(v.getStop());
    }
}

技术分享图片

分析:

stop变量加volatile就不会有这个问题了

四、Happen-Before

技术分享图片

五、线程安全的概念

指某个函数、函数库在多线程环境中被调用时,能够正确地处理各个线程的局部变量 ,使程序功能正确完成。

i++在多线程下访问的情况:

技术分享图片

以上是关于Java高并发-Java内存模型和线程安全的主要内容,如果未能解决你的问题,请参考以下文章

Java高并发-Java内存模型和线程安全

高并发编程之线程安全与内存模型

Java并发程序设计 Java内存模型和线程安全

Java并发编程与高并发解决方案 视频教程

java 关于多线程高并发方面

Java多线程与高并发-多线程内存模型