《实战Java高并发程序设计》学习记录3

原子性

要么全执行,要么都不做
这个比较熟悉,常见的如:

i++

还有32位虚拟机对64位虚拟机中Long型变量的操作也不是原子性的

有序性

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


    《实战Java高并发程序设计》学习记录3_第1张图片
    image.png

    《实战Java高并发程序设计》学习记录3_第2张图片
    image.png
  • 一条指令的执行是可以分为很多步骤的

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

《实战Java高并发程序设计》学习记录3_第3张图片
image.png

来个复杂点的


《实战Java高并发程序设计》学习记录3_第4张图片
image.png

《实战Java高并发程序设计》学习记录3_第5张图片
image.png

《实战Java高并发程序设计》学习记录3_第6张图片
image.png

可见性

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

– 编译器优化
– 硬件优化(如写吸收,批操作)

《实战Java高并发程序设计》学习记录3_第7张图片
image.png
  • 来看个代码
package someTest;

public class VisibilityTest extends Thread{
    private boolean stop;
    public void run() {
        int i=0;
        while(!stop) {
            i++;
            System.out.println("i="+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 InterruptedException {
        VisibilityTest v=new VisibilityTest();
        v.start();
        Thread.sleep(3000);
        v.stopIt();
        System.out.println("main finish");
        System.out.println(v.getStop());
    }
}

上面这段代码的意思就是根据标志位stop来决定是不是停止线程运行。看这意思应该是要停,可是真的会停吗?不会的,因为stop是不可见的。这是Java虚拟机层面的可见性问题
但我们加一个volatile修饰符怎么样?

package someTest;

public class VisibilityTest extends Thread{
    private volatile boolean stop;
    public void run() {
        int i=0;
        while(!stop) {
            i++;
            System.out.println("i="+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 InterruptedException {
        VisibilityTest v=new VisibilityTest();
        v.start();
        Thread.sleep(3000);
        v.stopIt();
        System.out.println("main finish");
        System.out.println(v.getStop());
    }
}

加上之后,由于这个stop标志位是内存可见的了,那么过一会儿,它就停了。

指令重排带来的问题

《实战Java高并发程序设计》学习记录3_第8张图片
image.png

happen before原则

《实战Java高并发程序设计》学习记录3_第9张图片
image.png

线程安全的概念

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

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


    《实战Java高并发程序设计》学习记录3_第10张图片
    image.png
  • 解决


    《实战Java高并发程序设计》学习记录3_第11张图片
    image.png

你可能感兴趣的:(《实战Java高并发程序设计》学习记录3)