1. 共享变量是指一个可以被多个线程访问的变量。
2. 一个对象是否线程安全取决于它是否被多个线程访问。
3. 只被单线程访问的对象永远是线程安全的。
4. 无论何时,只要有2个或2个以上的线程访问给定的变量,而且其中某个线程会写入该变量,此时必须使用同步机制来协调线程对该变量的访问。
5. Java中的基本的同步机制是synchronized关键字,它提供了独占锁。
6. 一开始就将一个类设计成线程安全的,比在后期重新修复它更容易。
7. 一个类是线程安全的,是指在被多个线程访问时,类可以持续进行正确的行为。
8. 线程安全的类封装了任何必要的同步,客户(类的使用者)不需要自己提供。
9. 无状态对象永远是线程安全的。如无状态Servlet是线程安全的。
// Java工程师在面试时,经常被问 Servlet是否线程安全的。其实不能盲目回答是还是不是,因为J2EE规范只是给我们提供了Servlet接口,我们可以自己设计实现,可以实现成无状态的Servlet,这时当然是线程安全的,然而有时,我们需要存储一些请求的信息到servlet类的实例变量中,这时必须要考虑线程安全问题。
10. 对全局变量,静态变量的只读操作,一般都是线程安全的。
11. 原子操作是指一个单独的不可分割的操作。
12. 非静态synchronized方法的锁就是该方法所在对象本身。静态synchronized方法的锁时从Class对象上获取。
13. 每个Java对象都可以隐式的扮演一个用于同步的锁(内部锁,独占锁)的角色。
14. 获得内部锁的唯一途径:进入这个内部锁保护的同步块或方法。
15. Java中的内部锁扮演互斥锁的角色,也就是同一时刻,最多只有一个线程拥有锁。
16. 每个共享变量都需要由唯一一个确定的锁保护。
17. 只有被多个线程访问的可变数据才需要锁的保护。
18. 锁保护的变量,每一次访问变量时,都需要先获得该锁,确保在同一个时刻只有一个线程可以访问这个变量。
19. 可见性:一个线程对某个变量的修改对其他线程是可见的。
20. 为了确保跨线程写入内存的可见性,必须使用同步机制。
21. 过期数据:一个线程无法取得某个变量的最新值,而得到的是先前的旧值。
22. 当一个线程在没有同步的情况下读取共享变量,得到的可能是一个过期值。
23. Volatile: java中用于同步的弱形式,用于保证可见性。
24. 读取一个Volatile变量,总会返回由某一个线程写入的最新值。
25. 对于当今大多数处理器架构,读取Volatile变量的开销只比读取非Volatile变量得开销略高。
26. 加锁可以保证可见性和原子性,Volatile变量只能保证可见性。
27. ThreadLocal:线程局部变量,用于线程见的数据隔离。ThreadLocal的get方法总是返回当前执行线程通过set设置的最新值。
28. 不可变对象永远是线程安全的。
29. 一个对象只有满足如下状态,才是不可变的:
a) 它的状态不能在创建后再被修改。
b) 它的所有域都是final类型的。
c) 它被正确的创建(创建的时候没有发生this溢出)。
30. 设计线程安全的类应该包括下边3个基本要素:
d) 确定对象状态是由哪些变量构成。
e) 确定限制状态变量的不变约束。
f) 制定一个管理并发访问对象状态的策略。