2010-12-14 95 views
5

有些情况下,您需要担心静态方法是否线程安全?您何时需要担心线程安全?

例如,如果我有静态工具函数不触及任何静态类级别变量,该方法是否已经线程安全?如果我有一个接触静态类变量的静态方法,该方法可能不是线程安全的吗?

在此先感谢。

回答

6

如果我有静态工具函数,它不会触及任何静态类级别的变量,那么该方法是否已经线程安全?

大部分时间 - 重要的是如果你的方法是reentrant。像这样的东西是折返的,因为一切都是局部变量,每个线程接收它自己的副本:

static int add(int a, int b) 
{ 
    return a + b; 
} 

还有一些事情要小心的。如果你将一个对象传递给方法,并且方法改变了对象,并且在方法完成之前,你可以在另一个线程上再次调用相同的方法,但是使用相同的对象,那么你有一个问题。

如果我有一个接触静态类变量的静态方法,该方法可能不是线程安全的吗?

主要问题再次是如果变量是可变的。如果你只是从不可变对象读取,那么可能没有任何问题。

如果你调用一个方法,并且你不确定它是否可重入,并且文档没有说,最好假定它不是。

+0

考虑*同时*读/写是不够的;如果内存不在屏障周围同步(如JMM所记录),则其中一个或其他线程可以观察陈旧的值,并且即使它们实际上没有实际冲突,写入的值也可能会丢失。出于同样的原因,即使只有一个编写器线程方案在没有某种内存障碍的情况下也会被破坏。 – 2010-12-15 04:06:42

3

只要您有多个线程访问相同的资源,您就必须担心线程安全问题。

如果您的静态方法使用与其他线程相同的资源(直接或间接),即使这些资源不是静态类变量,它也可能不安全。

+1

并且有两种线程共享数据的静态字段以外的其他方法。考虑静态无效MyClass.copy(来,从)方法。 – 2010-12-14 22:59:15

2

如果没有可变资源(例如类变量)被访问,那么它是线程安全的 - 但是,您必须确保您的方法不会调用访问任何可变资源的任何其他方法。

+0

但是,即使访问可变资源(如果访问已同步),它也可能是线程安全的。 – 2010-12-14 22:55:31

0

如果至少有一个可以被多个线程访问的入口点,线程安全就成为一个问题。

如果一段代码被多个线程访问并正在调用其他方法/类/ etc,那么所有的代码树都会变得易受攻击。

来自“实践中的Java并发”: 围绕任务执行组织程序的第一步是确定合理的任务边界。理想情况下,任务是独立的活动:不依赖于其他任务的状态,结果或副作用的工作不是 。独立性促进了并发性,因为如果存在足够的处理资源,独立任务可以并行执行。

例如,如果你正在编写一个孤立的servlet,它保证由一个线程执行,你不必担心。但是,如果您编写由不同servlet使用的静态实用程序,则必须处理多线程访问。

2

只要有多个线程访问相同的资源,您就必须担心线程安全问题,并且这些资源不是不可变的。

2

如果您有写入导致用户在多个线程共享(例如,静态变量,或多个线程使用任何物体)任何状态的方法,那么这个方法需要担心线程安全,等等做任何读取任何共享状态的方法。

5

如果在静态方法中只使用本地堆栈变量,那么没有理由担心。 java.lang.Math.min(int,int)就是这种方法的一个很好的例子。但是,如果你触摸任何共享的静态变量或者具有状态的对象(又名不可变),那么你必须使用同步。

+0

你的意思是“没有理由担心”在你的第一个礼让......? – 2010-12-14 22:57:59

+0

谢谢托尼。这是一个错字。 – 2010-12-14 22:59:24