我应该使我的所有Java代码线程安全吗?

时间:2009-09-08 04:42:45

标签: java multithreading concurrency

我正在阅读Brian Goetze的Java Concurrency in Practice中的一些并发模式,并对何时是使代码线程安全的正确时间感到困惑。

我通常编写的代码意味着在单个线程中运行,所以我不太担心线程的安全性和同步性等。但是,总是有可能在以后的某个时间段中重复使用相同的代码 - 环境。

所以我的问题是,什么时候开始考虑线程安全?我应该在开始时假设最坏的并且始终从头开始编写线程安全的代码,或者我是否应该重新访问代码并在以后需要时修改线程安全性?

是否存在一些并发模式/反模式,即使在编写单线程应用程序时也必须始终注意这些模式/反模式,以便我的代码在以后在多线程环境中使用时不会中断?

4 个答案:

答案 0 :(得分:12)

当您的代码将在多线程环境中使用时,您应该考虑线程安全性。如果它只能在单线程环境中运行,那么解决复杂性毫无意义。

话虽如此,你可以做的很简单的事情是好的做法,并且有助于多线程:

  1. 正如Josh Bloch所说,Favor Immutability。根据定义,不可变类是线程安全的;
  2. 仅在需要时使用数据成员或静态变量,而不是方便。

答案 1 :(得分:4)

使代码线程安全可以像添加注释一样简单,该注释表明该类不是为多线程并发使用而设计的。所以,在这个意义上:是的,你的所有类都应该是线程安全的。

但是,实际上,很多很多类型可能只被一个线程使用,通常只被引用为局部变量。即使程序作为一个整体是多线程的,也是如此。将每个对象安全地用于多线程访问是错误的。虽然惩罚可能很小,但它很普遍,并且可能会成为一个重要的,难以解决的性能问题。

答案 2 :(得分:2)

我建议你获得一份“Effective Java”,第二版。作者:Joshua Bloch。这本书用了整整一章来描述并发性,包括对同步时间(以及何时不存在)的问题的深入探索。请注意,例如,“有效Java”中的第67项标题:“避免过度同步”,详细说明超过五页。

答案 3 :(得分:1)

如前所述,当您认为您的代码将在多线程环境中使用时,您需要线程安全。

考虑Collections类所采用的方法,在这些类中,您提供了一个线程不安全的类,它在不使用synchronize的情况下完成所有工作,并且您还提供了另一个包装非同步类并提供它的类所有相同的公共方法,但使它们在底层对象上同步。

这使您的客户可以选择使用代码的多线程或单线程版本。它还可以通过在单独的类中隔离所有线程/锁定逻辑来简化编码。