16_03_Happen-Before原则的借助

Happen-Before原则的借助

Happen-Before 原则可以保证变量的可见性,因此可以通过 “借助” 的方式,来间接地实现对无锁保护变量的安全性保护。

“借助” 技术,一般将程序次序规则和其他某个规则(比如监视器锁规则或者 volatile 变量规则)结合起来实现的。

这种 “借助” 技术,对于代码语句的顺序非常敏感,因此很容易出错,属于一种高级技术。

 16_02_Java内存模型

Java内存模型

一、什么是内存模型?

缓存一致性问题:

  • 在多处理器系统中,每个处理器都有自己的高速缓存,而它们又共享同一主内存(Main Memory)
  • 当多处理器对同一块主内存区域进行操作时,可能会导致各自的缓存数据不一致,这就是缓存一致性问题

 16_01_并发问题来源

并发问题来源

一、缓存带来的可见性问题

  • 计算机中可以保存数据的地方有几个:寄存器、缓存、主内存
  • 原始数据都保存在主存上,最初的读取和最终的写入,都是在主存上操作
  • CPU 与主存之间存在缓存,每个 CPU 都有自己独立的的缓存
  • 操作数据时,首先要将原始数据从主存中读取到 CPU 的缓存中,然后再对缓存的数据进行操作
  • 单 CPU 下,一个线程对缓存的修改,对于另一个线程来说是可见的,因为只有一个缓存
  • 多 CPU 下,线程可能运行在不同 CPU 上,操作的是各自不同的缓存,相互之间是不可见的

 15_02_原子变量

原子变量

一、原子变量类

原子变量类相当于是一种泛化的 volatile 变量,能够支持原子和有条件的读写操作。

1.1 原子类型

  • 标量类:AtomicInteger、AtomicLong、AtomicBoolean、AtomicReference
  • 数组类:AtomicIntegerArray、AtomicLongArray、AtomicBooleanArray
  • 更新器类:AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicBooleanFieldUpdater
  • 复合变量类:AtomicMarkableReference

 15_01_CAS操作

CAS 操作

一、锁的劣势

  • 采用独占的方式访问锁的守护变量
  • 获取锁,存在挂起和恢复线程的问题,这些操作都比较耗时
  • 等待锁时,线程不能做其他的事情
  • 容易出现活跃性故障,比如死锁、活锁等
  • 锁竞争激烈时,线程调度开销会非常大

 14_条件队列

条件队列

一、状态依赖性管理

1.1、前提条件

类中一般有很多依赖于状态的方法,只有满足某些条件时才能正常执行。

比如说,在有界队列中的方法:

  • put 方法调用前,必须满足 !isFull() 条件
  • take 方法调用前,必须满足 !isEmpty() 条件

!isFull()!isEmpty() 这种被操作依赖的状态条件,称为前提条件。

 12_并发程序测试

并发程序测试

一、并发程序测试

1.1 并发测试的挑战

  • 潜在错误的发生具有不确定性,是随机的

1.2 并发测试的类型

1.2.1 安全性测试

  • 安全性:不发生任何错误的行为
  • 安全性测试:通常采用测试不变性条件和后验条件的形式,即判断某个类的行为在并发测试下,其状态是否与其规范一致

 10_活跃性问题

活跃性问题

一、死锁

1.1 死锁条件

  • 互斥:资源是互斥的,只能被一个线程持有
  • 占用且等待:线程占有一些资源后,在等待其他资源,等待过程中不会释放自己已占用的资源
  • 不可剥夺:不可以强行剥夺已被线程占有的资源
  • 循环等待:占用资源的线程在循环等待其他占用资源的线程释放资源