JAVA 并发相关总结
简介
自从JAVA 创建以来,java 就支持类似锁与线程的并发操作。本篇内容主要帮助JAVA 开发者理解和应用JAVA 的核心并发概念 以及如何应用。
概念
概念 | 介绍 |
---|---|
原子性 | 一个原子操作就是要么全部成功,要么全部失败 |
可见性 | 可见性是指 一个线程是否可以看到另一个线程的修改 |
表 1: 并发概念
条件竞争
竞争产生的条件是当一个以上线程对同一个共享对象发生一系列操作, 并且会根据不同线程的执行顺序不同产生不同的结果. 下面的代码就不是线程安全的 value
值会被初始化多次, 因为执行顺序 check-then-act
( 检测是否为 null
, 然后进行初始化) 导致懒加载的操作并不是原子性的:
class Lazy <T> { private volatile T value; T get() { if (value == null) value = initialize(); return value; } }
具体原因:... //todo
数据竞争
一个数据竞争产生的原因是 当超过两个线程尝试操作相同的 非 final 操作符定义的 变量并且没有使用synchronize 做线程同步的时候 。没有采用线程同步将会导致线程间的操作可见性, 产生的读取旧数据的情况 , 将会导致诸如无限循环、数据结构冲突、计算错误等情况 。下面的代码将会产生无限循环 ,因为读线程无法观察到 写线程的修改 :
class Waiter implements Runnable { private boolean shouldFinish; void finish() { shouldFinish = true; System.out.printf("should finish"); } public void run() { long iteration = 0; while (!shouldFinish) { iteration++; } System.out.println("Finished after: " + iteration); } } class DataRace { public static void main(String[] args) throws InterruptedException { Waiter waiter = new Waiter(); Thread waiterThread = new Thread(waiter); waiterThread.start(); Thread.sleep(2000); waiter.finish(); waiterThread.join(); } }
Java 内存模型: happens-before 关系
JAVA的内存模型或者说是读写操作,以及monitor的synchronize 操作 都是通称之为 happens-before relationship 进行排序的 .,
HAPPENS-BEFORE RELATIONSHIPS 拥有下列属性: |
---|
|
|
|
|
|
生命只有一次。