Java 程序设计(进阶) 版权所有 张玉帅 www.yushuai.me
第三章 线程(下)
3.1 线程安全与线程兼容与对立
线程安全:当多个线程访问同一个对象时,如果不同考虑这些线程在运行时环境下的调
度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这
个对象的行为都可以获得正确的结果,那这个对象是线程安全的。它包括:
(1)不可变。如果它访问的对象是不可修改的,那么它本身就是安全的。比如:
①final 修饰:public final a =100;
②java.lang.String: String s = “String”;string 常量
③枚举类型:public enum Color{RED,GREEN}
④java.lang.Number 的子类,比如 Long,Double
⑤BigInteger,BigDecimal(数值类型的高精度实现)
(2)绝对线程安全:满足上述定义的线程就为绝对县城安全,javaAPI 标注自己是线程
安全的类绝大多数不是绝对线程安全的。
(3)相对线程安全:通常意义上的线程安全,需要保证这个对象单独操作是线程安全
的,调用的时候不需要做额外的保障措施,但是对于一些特定顺序的连续调用,就需要在调
用时使用同步手段保证调用的正确性。如 Vector,HashTable 等。
(4)线程的兼容和对立。线程兼容指对象本身不是线程安全的,但是可以通过在调用
端正确地使用同步手段来保证对象在并发环境中可以安全使用;线程对立是无论调用端是否
采用了同步措施,都无法在多线程环境中并发使用的代码。
3.2 线程的安全实现——互斥同步
同步的互斥实现方式:临界区、互斥量、信号量 。解决的方式就是使用 Synchronized
关键字,经过编译后,会在同步块前后行程 monitorenter 和 monitorexit 两个字节码。
synchronized 同步块对自己是可重入的,不会将自己锁死;同步块在已进入的线程执行完之
前,会阻塞后面其它线程的进入,以保证程序安全性。
还有一种方式是重入锁(java.util.concurrent)。相比采用 synchronized,重入锁可实现:
等待可中断、公平锁、锁可以绑定多个条件。Synchronized 表现为原生语法层面的互斥锁,
而 RenentrantLock 表现为 API 层面的互斥锁。
他们的性能比较如图 1 所示。
图 1
3.3 线程的安全实现——非阻塞同步
1.阻塞同步:互斥同步存在的问题是进行线程阻塞和唤醒所带来的性能问题,这种同步
称为阻塞同步。这是一种悲观并发策略。
2.非阻塞同步:不同于前者,它是基于冲突检测的乐观并发策略,就是先进行操作,如
评论0