【并发编程学习01-3大特性,可见性有序性原子性】

并发编程3大特性学习

一,理论知识

并行与并发:
1)目标都是最大化的利用cpu
2)区别:
并行:同一时刻,多个线程在多个cpu上同时执行
在这里插入图片描述
并发:同一时刻,只能有1条指令执行,但是多个指令快速轮换执行。(一次线程上下文切换约5~10ms)
在这里插入图片描述
并行在多处理器系统中存在,并发在单处理器和多处理器中都存在。

JMM模型:

并发编程3大特性:
1)可见性
2)有序性
3)原子性

理解:
1)可见性
一个线程修改了共享变量的值,其他线程能够看到这个修改后的值。就叫可见性。
如何保证可见性:
总结下来 可以通过内存屏障,线程上下文切换达到可见性。
具体为:

  • 通过volatile关键字保证
  • 通过内存屏障
  • 通过sychronized
  • 通过lock
  • 通过final

volatile的读写语义:
当写入一个变量时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。
当读取一个变量时,JMM会该线程对应的本地内存中的共享变量失效,线程接下来会从主内存中读取共享变量。

volatile实现原理:
通过内存屏障,在jvm层面会调用storeload,在x86处理器中,汇编语言层面,会加上lock 前缀指令。
lock前缀指令:
1)类似于内存屏障的功能,禁止该指令与前面后面的读写指令重排序。
2)会等待它之前的所有指令都完成,并且所有缓冲的写操作都写回内存之后在开始执行。

可见性实验代码:


import java.util.concurrent.CompletableFuture;

public class VisibilityTe {


    public static void main(String[] args) {

        MyThreadVisibility threadVisibility = new MyThreadVisibility();

        // 用这个,即使线程没执行完,一样会停止。
//        CompletableFuture.runAsync(threadVisibility::runAddCount);
        Thread thread01 = new Thread(threadVisibility::runAddCount, "thread01");
        thread01.start();
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        Thread thread02 = new Thread(threadVisibility::refresh, "thread02");
        thread02.start();

    }

    static class MyThreadVisibility {

        private boolean FLAG = true;
        private int num = 0;

        public void refresh() {

            FLAG = false;
            System.out.println(Thread.currentThread().getName() + "将flag设置为false");
        }

        public void runAddCount() {
            System.out.println(Thread.currentThread().getName() + "开始执行");

            while (FLAG) {
                num++;
            }
            System.out.println(Thread.currentThread().getName() + "执行完成num:" + num);
        }
    }

}

上述代码执行后,thead01感知不到thread02对flag的修改。
要想能做到感知可以:

  • 给flag 加volatile(给num 加一样可以)
  • 在while(){}内,使用Thread.yield();让出时间片,上下文切换,线程本地缓存失效,重新读取主存数据
  • 在while(){}内,使用sout打印。sout源码有使用sychronized
  • 或者将num 改成Integer类型,因为Integer类,内部使用到了final

2)有序性:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值