美文网首页
深入理解 Java 虚拟机读书笔记8

深入理解 Java 虚拟机读书笔记8

作者: jkwen | 来源:发表于2021-02-02 16:20 被阅读0次

这部分内容是从高效并发的角度来谈论 Java 虚拟机如何处理多线程相关的问题。

计算机被要求并发执行的原因是:
1.处理器有这个能力 24 小时不间断高效的做任务。
2.由于从存储设备读写数据的速度远慢于处理器的运算速度,导致处理器会存在空闲等待的情况,为了避免等待,要求同时处理多个任务。

为了缩小这个速度差距,引入了一层缓存区,内存的数据会被先读到缓存,再读到处理器,同样写数据也是。由于内存是多线程(也就是多任务)共享的,这又导致另一个问题:缓存一致性。为了解决这个问题,处理器们就要遵循一套规范,协议来对缓存数据进行访问。

Java 内存模型

抽象的内存模型为的是屏蔽掉底层具体的硬件实现,达到跨平台的效果。这套模型的定义很大程度上也是为了解决并发内存访问的问题。模型始终围绕着并发过程中的原子性,可见性,有序性展开。

  • 原子性
    主要就是指基本数据类型的原子操作(long 和 double 类型的非原子协定),另外 synchronized 同步锁操作也具备原子性。
  • 可见性
    即某个线程修改了变量值,其他线程能立马知道这个修改。volatile 能在值修改后立即刷到主内存,在读取前保证工作内存的值是从主内存里刷新过来的。synchronized 和 final 也能保证可见性。
  • 有序性
    对单线程来说肯定是有序的。volatile 因为禁止了指令重排序优化,所以可以有序,synchronized 作为同步锁,自然也是有序的。 其余情况,java 将根据“先行发生”原则保证有序。

原子操作

相对于硬件上的内存和缓存,Java 内存模型定义了主内存与工作内存与之对应,并规定访问协议为以下 8 种操作,且每种操作都具有原子性。

  • lock
  • unlock
  • read
  • load
  • use
  • assign
  • store
  • write

volatile

是 Java 虚拟机提供的最轻量级的同步机制,当变量定义为 volatile 之后,它就具有对所有线程的可见性(即可以认为没有缓存不一致的问题,但不代表在多线程的情况下是安全的),如果要用 volatile 进行同步操作,首先要满足两个条件,否则还是建议用上同步锁,

  1. 运算结果不依赖变量的当前值,或能保证运行在单线程环境
  2. 变量不需要与其他的状态变量共同参与不变约束

另一个特性是禁止指令重排序优化。Java 代码在执行时会进行指令重排序优化,即过程可能不像我们代码写的那样的顺序,不过结果还是我们期望的结果,但这在多线程的时候,就有可能出问题,多线程需要必须保证顺序的正确性, volatile 可以避免重排序。

long 和 double 的特例

在谈论 long 和 double 类型时,前面说的 8 种原子操作中,load, store, read, write 可以不成立,即 long 和 double 的非原子性协定。

线程

线程的底层实现可以基于内核线程,用户线程或用户线程加轻量级进程混合,Java 线程的实现是基于操作系统原生线程模型来实现的。

Java 线程调度方式为抢占式调度,线程可以设置优先级来控制执行时间的多少,但优先级控制并不可靠;另外一种调度方式就是协同式调度。

线程安全

我们可以从 5 个方面来理解线程安全,

  • 不可变性
    拥有不可变特性的变量,对象等不管是单线程还是多线程都是安全的,例如 final 修饰的变量,String 类,枚举类,Long,Double 等数值包装类,BigInteger, BigDecimal 等。
  • 相对线程安全
    这是我们通常认为的线程安全,Java 类中说明是线程安全的主要就是指这种情况。它指的是在没有特殊需求的情况下(指的是单独操作),可以保证线程安全,其他情况可以借助同步手段来保证线程安全。例如 HashTable,Vector 这种线程安全的集合类
  • 线程兼容
    即本身不保证线程安全,但通过同步手段可以做到线程安全。例如 HashMap, ArrayList 等。
  • 绝对线程安全
    几乎不可能,因为要求的条件很严格。
  • 线程对立
    这种情况会造成线程的死锁。

互斥同步是确保线程安全的实现方式,通过互斥的手段达到线程同步访问某个代码段,从而保证线程安全。

相关文章

网友评论

      本文标题:深入理解 Java 虚拟机读书笔记8

      本文链接:https://www.haomeiwen.com/subject/fgpytltx.html