java 对静态方法的并发访问

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14126556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 15:09:58  来源:igfitidea点击:

Concurrent access to static methods

javamethodsconcurrencystaticsimultaneous

提问by user1226058

I have a static method with the following signature:

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

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

What happens when there are multiple calls made to the above method concurrently? Will the requests be handled concurrently or one after the other?

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

回答by Andremoniy

Answering exactly your question:

准确回答你的问题:

  1. Method will be executed concurrently (multiple times in the same time if you have several threads).
  2. Requests will be handled concurrently.
  1. 方法将并发执行(如果您有多个线程,则在同一时间多次执行)。
  2. 请求将被并发处理。

You need to add the synchronizedmodifier if you are working with objects that require concurrent access.

synchronized如果您正在处理需要并发访问的对象,则需要添加修饰符。

回答by ben75

All your calls to the method will be executed concurrently... but:

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

You may have concurrency issue (and being in non thread-safe situation) as soon as the code of your static method modify static variables. And in this case, you can declare your method as synchronized

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

If your method only use local variables you won't have concurrency issues.

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

回答by Ted Hopp

If you need to avoid concurrent execution, you need to explicitly synchronize. The fact that the method is static has nothing to do with it. If you declare the method itself to be synchronized, then the synchronization will be on the class object. Otherwise you will need to synchronize on some static object (since thisdoesn't exist for static methods).

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

回答by swayamraina

I see a lot of answers but none really pointing out the reason.

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

So this can be thought like this,
Whenever a thread is created, it is created with its own stack (I guess the size of the stack at the time of creation is ~2MB). So any execution that happens actually happens within the context of this thread stack.
Any variable that is created lives in the heap but it's reference lives in the stack with the exceptions being static variables which do not live in the thread stack.

所以这可以这样想,
每当一个线程被创建时,它都是用自己的堆栈创建的(我猜创建时堆栈的大小是~2MB)。因此,发生的任何执行实际上都发生在该线程堆栈的上下文中。
创建的任何变量都存在于堆中,但它的引用存在于堆栈中,但不存在于线程堆栈中的静态变量除外。

Any function call you make is actually pushed onto the thread stack, be it static or non-static. Since the complete method was pushed onto the stack, any variable creation that takes place lives within the stack (again exceptions being static variables) and only accessible to one thread.

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

So all the methods are thread safe until they change the state of some static variable.

所以所有的方法都是线程安全的,直到它们改变一些静态变量的状态。

回答by Raffaele

You can check it yourself:

你可以自己检查一下:

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");
    }

}

回答by jtahlborn

all method invocations from separate threads in java are concurrent by default.

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