java 并发编程(待修改)

并发编程涉及线程的分工、同步与协作,以及处理可见性、原子性和有序性问题。文章介绍了volatile关键字解决可见性,synchronized和CAS确保原子性,以及JMM确保有序性的概念。并提到了Unsafe类提供的硬件级别原子操作。
摘要由CSDN通过智能技术生成

一 并发的概念

首先能用一个线程完成的事就不要用多线程做。

分工

并发编程 本质上是将原来一个线程做的事分给多个线程做(分工)

常⻅的 Executor,⽣产者-消费者模式,Fork/Join 等,这都是分⼯思想 的体现

同步/协作

        将一个整体的任务分为几个任务段之前 要进行通信,讨论怎么完成一个整体的任务,比如当一个线程执行完后,如何通知后续其他线程执行。

线程之间的协作可能是主线程与⼦线程的协作,可能是⼦线程与 ⼦线程的合作, Java SDK 中 CountDownLatch 和 CyclicBarrier 就是⽤来解决线 程协作问题的

互斥

分⼯和同步强调的是性能,但是互斥是强调正确性---线程安全

互斥--同一时刻,只允许一个线程访问共享变量

当多个线程同时访问⼀个共享变量/成员变量时,就可能发⽣不确定性,造成 不确定性主要是有 可⻅性 、 原⼦性 、 有序性 这三⼤问题,⽽解决这些问题的核⼼ 就是互斥

二 并发编程三大问题

可见性,原⼦性,和有序性

为什么会出现这三种问题呢?

在线程执行中,涉及到 CPU,内存与 IO ,但是三者的运行速度差异很大 CPU > 内存 > IO分

那为了尽可能的利用CPU ,从而提升整体的效率,怎么做呢?

1. CPU 增加缓存,还不⽌⼀层缓存,平衡内存的慢
2. CPU 能者多劳,通过分时复⽤,平衡 IO 的速度差异
3. 优化编译指令

经过以上的优化,效率高了,那问题也产生了。

可见性 

一个线程对共享变量的修改,另外一个线程能够立刻看到,我们称为可见性  volatile解决谈到可⻅性,要先引出 JMM (Java Memory Model) 概念, 即 Java 内存模型,Java 内存模型规定,将所有的变量都存放在 主内存 中,当线程使⽤变量时,会把主内存 ⾥⾯的变量 复制 到⾃⼰的⼯作空间或者叫作 私有内存 ,线程读写变量时操作的是 ⾃⼰⼯作内存中的变量。

在 Java 中,所有的实例域,静态域和数组元素都存储 在堆内存中,堆内存在线程之间共享,这些在后续⽂章中都称之为「共享变 量」,局部变量,⽅法定义参数和异常处理器参数不会在线程之间共享,所以 他们不会有内存可⻅性的问题,也就不受内存模型的影响

⼀句话,要想解决多线程可⻅性问题,所有线程都必须要刷取主内存中的变量 怎么解决可⻅性问题呢?

Java 关键字 volatile 帮你搞定

原子性 :所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch

如何保证多个操作的原⼦性呢?最粗暴的⽅式是在⽅法上加 synchronized 关键字

synchronized 是独占锁 (同⼀ 时间只能有⼀个线程可以调⽤),没有获取锁的线程会被阻塞;另外也会带来很多线 程切换的上下⽂开销

所以 JDK 中就有了⾮阻塞 CAS (Compare and Swap) 算法实现的原⼦操作类 AtomicLong 等⼯具类

private  static  final  Unsafe unsafe = Unsafe.getUnsafe();

这个类是 JDK 的 rt.jar 包中的 Unsafe 类提供了 硬件级别 的原⼦性操作,类中的 ⽅法都是 native 修饰的


有序性 

编译器会为了执行效率 擅自优化代码顺序

  • 可⻅性/原⼦性/有序性 三个问 题,这些问题通常违背我们的直觉和思考模式,也就导致了很多并发 Bug
  • 为了解决 CPU,内存,IO 的短板,增加了缓存,但这导致了可⻅性问题 编译器/处理器 擅⾃ 优化 ( Java代码在编译后会变成 Java 字节码, 字节码被 类加载器加载到 JVM ⾥, JVM 执⾏字节码, 最终需要转化为汇编指令在 CPU 上执⾏) ,导致有序性问题

有序性可见性,happens-before

1. 对于会改变程序执⾏结果的重排序,JMM要求编译器和处理器必须禁⽌这种重 排序。
2. 对于不会改变程序执⾏结果的重排序, JMM对编译器和处理器不做要求 (JMM 允许这种重排序)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值