并发访问静态方法

时间:2013-01-02 17:39:35

标签: java methods concurrency static simultaneous

我有一个带有以下签名的静态方法:

public static List<ResultObjects> processRequest(RequestObject req){
  // process the request object and return the results.
}

当同时对上述方法进行多次调用时会发生什么?请求是同时处理还是一个接一个地处理?

6 个答案:

答案 0 :(得分:24)

完全回答你的问题:

  1. 方法将同时执行(如果您有多个线程,则同时多次执行)。
  2. 请求将同时处理。
  3. 如果您正在处理需要并发访问的对象,则需要添加synchronized修饰符。

答案 1 :(得分:13)

如果需要避免并发执行,则需要显式同步。该方法是静态的这一事实与它无关。如果将方法本身声明为synchronized,则同步将在类对象上。否则,您将需要在某个静态对象上进行同步(因为静态方法不存在this)。

答案 2 :(得分:11)

您对方法的所有调用都将同时执行......但是:

一旦静态方法的代码修改静态变量,就可能出现并发问题(并且处于非线程安全状态)。在这种情况下,您可以将方法声明为synchronized

如果您的方法仅使用局部变量,则不会出现并发问题。

答案 3 :(得分:2)

您可以自己查看:

public class ConcurrentStatic {

    public static void main(String[] args) {
        for (String name: new String[] {"Foo", "Bar", "Baz"}) {
            new Thread(getRunnable(name)).start();
        }
    }

    public static Runnable getRunnable(final String name) {
        return new Runnable() {
            public void run() {
                longTask(name);
            }
        };
    }

    public static void longTask(String label) {
        System.out.println(label + ": start");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(label + ": end");
    }

}

答案 4 :(得分:1)

默认情况下,来自java中不同线程的所有方法调用都是并发的。

答案 5 :(得分:0)

我看到了很多答案,但没有一个真正指出原因。

所以可以这样想,
每当创建线程时,都会使用自己的堆栈来创建线程(我猜创建时堆栈的大小约为2MB)。因此,任何发生的执行实际上都发生在此线程堆栈的上下文中。
创建的任何变量都存在于堆中,但其引用存在于堆栈中,但静态变量不在线程堆栈中。

您进行的任何函数调用实际上都被推送到线程堆栈上,无论是静态的还是非静态的。由于将完整方法压入堆栈,因此任何发生的变量创建都存在于堆栈中(同样是静态变量),并且只能由一个线程访问。

因此,所有方法在更改某些静态变量的状态之前都是线程安全的。