我有一个具有以下签名的静态方法:
public static List<ResultObjects> processRequest(RequestObject req){
// process the request object and return the results.
}
当同时对上述方法进行多次调用时会发生什么?请求是同时处理还是一个接一个?
我有一个具有以下签名的静态方法:
public static List<ResultObjects> processRequest(RequestObject req){
// process the request object and return the results.
}
当同时对上述方法进行多次调用时会发生什么?请求是同时处理还是一个接一个?
准确回答您的问题:
synchronized
如果您正在处理需要并发访问的对象,则需要添加修饰符。
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
If your method only use local variables you won't have concurrency issues.
如果需要避免并发执行,则需要显式同步。该方法是静态的这一事实与它无关。如果您将方法本身声明为synchronized
,则同步将在类对象上进行。否则,您将需要在某些静态对象上进行同步(因为this
静态方法不存在)。
我看到很多答案,但没有一个真正指出原因。
所以可以这样想,
每当创建一个线程时,它都会用自己的堆栈创建(我猜创建时堆栈的大小是~2MB)。所以发生的任何执行实际上都发生在这个线程堆栈的上下文中。
创建的任何变量都存在于堆中,但它的引用存在于堆栈中,但不存在于线程堆栈中的静态变量除外。
您进行的任何函数调用实际上都被推入线程堆栈,无论是静态的还是非静态的。由于完整的方法被压入堆栈,因此发生的任何变量创建都存在于堆栈中(同样例外是静态变量)并且只能由一个线程访问。
所以所有的方法都是线程安全的,直到它们改变了一些静态变量的状态。
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");
}
}
默认情况下,Java 中不同线程的所有方法调用都是并发的。