我有一个带有以下签名的静态方法:
public static List<ResultObjects> processRequest(RequestObject req){
// process the request object and return the results.
}
当同时对上述方法进行多次调用时会发生什么?请求是同时处理还是一个接一个地处理?
答案 0 :(得分:24)
完全回答你的问题:
如果您正在处理需要并发访问的对象,则需要添加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)。因此,任何发生的执行实际上都发生在此线程堆栈的上下文中。
创建的任何变量都存在于堆中,但其引用存在于堆栈中,但静态变量不在线程堆栈中。
您进行的任何函数调用实际上都被推送到线程堆栈上,无论是静态的还是非静态的。由于将完整方法压入堆栈,因此任何发生的变量创建都存在于堆栈中(同样是静态变量),并且只能由一个线程访问。
因此,所有方法在更改某些静态变量的状态之前都是线程安全的。