- 线程安全:当多个线程访问某个类时,不管运行时环境采用和种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。
- 竞态条件:基于一种可能失效的观察结果来做出判断或者执行某个计算。这种类型的竞态条件称为“先检查后执行”,常见的例子就是i++,以及if(condition) then dosometing。
- 数据竞争:容易跟竞态条件混淆,指如果在访问共享的非final类型的域时没有采用同步来协同,那么就会出现数据竞争,常见于java内存模型。
- 内置锁,监视器锁:本质是互斥锁,Monitor enter,Monitor exit
- 内存可见性:防止某个线程正在使用对线状态而另外一个线程在同时修改该状态,确保当一个线程修改了对象状态后,其他线程能够看到发生的状态变化。
- 重排序:以下这段代码可能存在重排序问题导致输出为0。 0.0
-
1 public class NoVisibility { 2 private static boolean ready; 3 private static int number; 4 5 private static class ReaderThread extends Thread { 6 public void run() { 7 while (!ready) 8 Thread.yield(); 9 System.out.println(number); 10 } 11 } 12 13 public static void main(String[] args) { 14 new ReaderThread().start(); 15 number = 42; 16 ready = true; 17 } 18 }
- 非原子性的64位操作:对于非volatile类型的long和double变量,JVM允许将64位的读操作或者写操作分解为两个32位操作。当读取一个非volatile类型的long变量时,如果对该变量的读操作和写操作在不同的线程中,可能读取的是A的高32位,B的低32位。
- 如果对不同的锁进行同步,不能实现线程安全
@NotThreadSafe class BadListHelper <E> { public List<E> list = Collections.synchronizedList(new ArrayList<E>()); public synchronized boolean putIfAbsent(E x) { boolean absent = !list.contains(x); if (absent) list.add(x); return absent; } } @ThreadSafe class GoodListHelper <E> { public List<E> list = Collections.synchronizedList(new ArrayList<E>()); public boolean putIfAbsent(E x) { synchronized (list) { boolean absent = !list.contains(x); if (absent) list.add(x); return absent; } } }