如果非同步静态方法不修改静态类变量,那么它们是否安全?

问题

我想知道你是否有一个静态方法是而不是synchronised,但do不是修改任何静态变量它是线程安全的吗?如果方法在其中创建局部变量怎么办?例如,以下代码是否是线程安全的?

public static String[] makeStringArray( String a, String b ){
    return new String[]{ a, b };
}

因此,如果我有两个线程连续和同时调用该方法,一个与狗(说"大丹狗"和"斗牛犬")和另一个与猫(说"波斯语"和"暹罗")将我会得到猫和狗在同一个阵列?或者猫和狗不会同时在同一个方法的调用内?


#1 热门回答(204 赞)

这种方法是100%线程安全的,即使它不是static也是如此。当你需要在线程之间共享数据时,会出现线程安全问题 - 你必须注意原子性,可见性等。

此方法仅对参数进行操作,这些参数驻留在堆栈上,并且对堆上的不可变对象的引用.堆栈本质上是线程的本地,因此不会发生数据共享。

不可变对象(在这种情况下为String)也是线程安全的,因为一旦创建它们就无法更改,并且所有线程都看到相同的值。另一方面,如果方法接受(可变)Date你可能有问题。两个线程可以同时修改同一个对象实例,从而导致竞争条件和可见性问题。


#2 热门回答(27 赞)

一种方法在更改某些共享状态时只能是线程不安全的。它是静态的还是无关紧要的。


#3 热门回答(12 赞)

该功能完全是线程安全的。

如果你想一想......假设如果不同会发生什么。如果不同步,每个常用函数都会出现线程问题,因此JDK中的所有API函数都必须同步,因为它们可能被多个线程调用。而且由于应用程序大部分时间都在使用某些API,因此多线程应用程序实际上是不可能的。

考虑它太荒谬了,所以只为你自己:如果有明显的原因可能存在问题,方法就不是线程安全的。尝试总是考虑如果我的函数中有多个线程会怎么样,如果你有一个步调试器并且一步一步推进第一个...那么第二个线程...也许第二个线程......会有问题吗?如果你找到一个,它不是线程安全的。

请注意,大多数Java 1.5 Collection类都不是线程安全的,除了那些陈述的类,如ConcurrentHashMap。

如果你真的想深入了解这一点,请仔细查看volatile关键字及其所有副作用。看一下Semaphore()和Lock()类,以及他们在java.util.Concurrent中的朋友。阅读课程周围的所有API文档。值得学习和满足。

对不起这个过于精细的答案。