静态方法会阻塞吗?

7

假设我有一个定义如下的类:

public class MyClass {

    private static int data;

    public static staticMethod(int val){
      ... do something with data based on val ...
    }
}

现在假设我的应用程序中有许多Java线程正在运行,它们调用静态方法

MyClass.staticMethod(int)

这个方法会在每次调用时阻塞吗?即,如果线程1首先调用该方法并且在执行该方法的运行期间,线程2调用静态方法,那么第二个线程是否必须等待第一个执行完毕?

如果答案是否定的,那么什么时候使用非同步的静态数据成员才有意义呢?


3
你为什么不试试看呢? - SevenBits
5
@SevenBits,因为并发问题通常只有在高并发时才会显现出来,所以通过设计来排除它们的努力通常会为自己付出。这种“试错”方法来理解规范往往会导致代码能正常运行,直到问题变得紧要。 - Mike Samuel
1
尝试这个并观察结果仍然是相当简单的。 - Dawood ibn Kareem
4个回答

8
不,这不是static关键字的一部分。如果您想同步两个访问同一方法的线程,请使用其他可能性,例如synchronized方法语句),或来自java.util.concurrent包的内容。

6

这个方法每次调用都会阻塞吗?

不会。普通的 static 方法不会阻塞其他线程。(但是一个 static synchronized 方法可以阻塞其他线程... 或被其他线程阻塞。)

如果答案是否定的,那么什么情况下使用未“同步”的静态数据成员才有意义?

  • 如果数据成员是 volatile 的话,那么使用未同步的方式也是可以的......尽管 volatile 有其局限性。

  • 如果数据成员是指向线程安全类型的 final 引用,则可以使用未同步的方式。

  • 如果数据成员是线程封闭的话,那么也可以使用未同步的方式。(这种情况很少见,因为该成员变量因为是静态的而对所有线程可见。但这是可能的。)

  • 如果其他某个机制正在负责同步,或者如果您正在使用 Lock 对象进行互斥等等......尽管您可能会说这些 "不算"。


4

根据您所写的内容,不行。多线程不会等待其他线程完成方法执行。无论这个方法是 static 还是非 static,情况都是如此。

如果要确保只有一个线程访问该方法,必须将该方法设为synchronized

public static synchronized staticMethod(){

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接