Java 杂谈

关于绝对线程安全和相对线程安全的思考

2016-07-13  本文已影响0人  ColdCode1984

Brian Goetz的《Java并发编程实战》有对线程安全的定义:

“当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替进行,并且在主调
代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么称这个类是线程安全的。”

周志明在《深入理解JVM》中认为上述线程安全的定义是一个非常严谨的绝对线程安全的定义,并认为上述定义在大多数应用场景下难以实现或必须付出不切实际的代价才可以实现。周认为这个定义可以适当弱化,把“调用这个对象的行为”限定为“单次调用”,这样一来就可以得到相对线程安全的定义,而实际上JDK中绝大多数的类都是相对线程安全的类,即线程安全的意义是建立在“单次调用”的基础上。
但其实这种特例式的弱化并不能很好的揭示绝对线程安全和相对线程安全的区别与联系。
周在书中呈现了一个事例来展现绝对线程安全与相对线程安全的区别:

代码参见《深入理解JVM》P388。

例子中反复创建多个remove线程和get线程分别对同一个vector(已初始化并填充了适量元素)进行remove和get操作,最终结果可想而知,抛出ArrayIndexOutOfBoundsException。周认为这是由于多线程环境下调用端没有做额外同步措施造成的线程不安全,进而可以说vector类是相对线程安全的类。
其实有更好的理解,根据Brian Goetz的绝对线程安全类定义,我们可以说Vector类本身就不是一个绝对线程安全的类,因为它并不满足绝对线程安全的定义,即不能保证调用端任何调用(特别是针对未来客户端可能产生的各种需求)都是线程安全的,在这个例子中Vector并没有提供一种一致性的快照访问,或者说实际中很难实现,这也就是周书中提到的:

“Brian Goetz的绝对线程安全类定义是非常严格的,要实现一个绝对线程安全的类通常需要付出很大
的、甚至有时候是不切实际的代价”。
上一篇下一篇

猜你喜欢

热点阅读