并发三大特性

1. 原子性

即保证操作不可中断,只能执行或者不能执行

在 java 中只有简单的赋值和读取是原子性操作,而对于复杂业务而言,这需要使用 synchronized 和 Lock
来实现,因为同一时段只能保证一个线程操作,就不会有原子性问题

2. 可见性

提供了 volatile 关键字,保证一旦有更新就更新到主存中去,同时 synchronized 和 Lock 也可以实现,因为线程操作完后,会将变量修改刷新到主存之中

3. 有序性

java 中有指令重排序,单线程会保证结果一致,多线程就不一定,可以通过 volatile 保证一定有序性,也可以让 synchronized 和 Lock
保证只有一个线程运行,即也保证了有序性。

java 中先天性具有有序性,使用了 happends-before 原则

下面就来具体介绍下 happens-before 原则(先行发生原则):

  • 程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
  • 锁定规则:一个 unLock 操作先行发生于后面对同一个锁额 lock 操作
  • volatile 变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作
  • 传递规则:如果操作 A 先行发生于操作 B,而操作 B 又先行发生于操作 C,则可以得出操作 A 先行发生于操作 C
  • 线程启动规则:Thread 对象的 start() 方法先行发生于此线程的每个一个动作
  • 线程中断规则:对线程 interrupt() 方法的调用先行发生于被中断线程的代码检测到中断事件的发生
  • 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过 Thread.join()方法结束、Thread.isAlive()
    的返回值手段检测到线程已经终止执行
  • 对象终结规则:一个对象的初始化完成先行发生于他的 finalize() 方法的开始