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

我想知道如果你有一个静态的方法,是 没有同步,但是 没有修改任何静态变量是线程安全的吗?如果该方法在其中创建局部变量会怎样?例如,下面的代码是否是线程安全的?

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

因此,如果我有两个线程连续并发地调用 th 方法,其中一个线程调用的是狗(比如“ great dane”和“ bull dog”) ,另一个线程调用的是猫(比如“ persian”和“ siamese”) ,那么猫和狗会出现在同一个数组中吗?或者猫和狗永远不会在同一时间在同一个方法调用中?

63744 次浏览

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

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

不可变对象(本例中为 String)也是线程安全的,因为一旦创建它们就不能更改,所有线程都会看到相同的值。另一方面,如果该方法接受(可变的) Date,您可能有一个问题。两个线程可以同时修改同一个对象实例,从而导致竞态条件和可见性问题。

一个方法只有在改变某种共享状态时才可能是线程不安全的。它是静态的还是非静态的并不重要。

该函数是完全线程安全的。

如果你仔细想想... 想象一下如果情况不同,会发生什么。如果不同步,每个常见的函数都会有线程问题,所以 JDK 中的所有 API 函数都必须同步,因为它们可能会被多个线程调用。而且由于大多数时候应用程序都使用一些 API,多线程应用程序实际上是不可能的。

这种想法太荒谬了,所以只对您而言: 如果存在明确的问题原因,那么方法就不是线程安全的。试着想一想,如果我的函数中有多个线程,如果你有一个步骤调试器,并且一步一步地推进第一个... 然后第二个线程... 也许第二个线程... 会有问题吗?如果你找到一个,它不是线程安全的。

还请注意,大多数 Java 1.5 Collection 类都不是线程安全的,除了那些已经声明的类,比如 ConcurrentHashMap。

如果你真的想深入研究这个问题,那么就仔细研究一下易失性关键字和它的所有副作用吧。查看 Semaphore ()和 Lock ()类,以及它们在 java.util 中的朋友。同时进行。阅读类周围的所有 API 文档。这也是值得学习和满足的。

抱歉我的回答过于复杂了。

字符串对象是不可变的是上述线程安全场景的另一个原因。相反,如果使用可变对象(例如 make MutableArray)。.)那么线程安全肯定会被打破。

使用具有同步静态方法的 static关键字修改线程之间共享的静态数据。使用 static关键字创建的所有线程将争夺该方法的单个版本。

使用 volatile关键字和同步实例方法将保证每个线程都有自己的共享数据副本,并且不会在线程之间泄漏读/写操作。

由于完整的方法被推送到堆栈上,所有发生的变量创建都存在于堆栈中(同样,静态变量也是例外) ,并且只有一个线程可以访问。所以所有的方法都是线程安全的,直到它们改变某个静态变量的状态。

参见:

静态方法在 Java 中是线程安全的吗?