Java 当两个线程同时调用同一个静态方法时会发生什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21864807/
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
What happens when two threads call the same static method at the same time?
提问by Ernestas Gruodis
What happens when two threads call the same static method at the same time? For example:
当两个线程同时调用同一个静态方法时会发生什么?例如:
public static String someMethod(){
//some logic, can take about 1 second to process
return new String(result);
}
First thread calls someMethod() now. Second thread calls someMethod() 0.5 seconds from now (first thread still processing the data).
第一个线程现在调用 someMethod() 。第二个线程在 0.5 秒后调用 someMethod()(第一个线程仍在处理数据)。
I know that someMethod() can be synchronized. But what will happen if it's not synchronized?
我知道 someMethod() 可以同步。但是如果不同步会发生什么?
采纳答案by user60561
It depends on whether your method changes outside state.
这取决于您的方法是否在外部状态发生变化。
static long i = 0l;
public static String someMethod(){
String accm = "";
for(;i < Integer.MAX_VALUE*20/*Just to make sure word tearing occurs*/; i++)
accm += i
return accm;
}
Will cause problems:
会导致问题:
- Longs are not guaranteed to be set atomically, so they might be 'torn' (Spec)
++
is not an atomic operation. It is exactly the same as{int n = i; i = i + 1; return n}
i = i + 1
is also not atomic, if it changes in the middle, some values will be repeated- The return of n might be stale
- 不能保证以原子方式设置多头,因此它们可能会被“撕裂”(Spec)
++
不是原子操作。它与完全相同{int n = i; i = i + 1; return n}
i = i + 1
也不是原子的,如果在中间发生变化,一些值会重复- n 的返回可能是陈旧的
But if i
is a local variable, there will be no problems. As long as any outside state is guaranteed to be immutable while it is being read, there can never be any problems.
但是如果i
是局部变量,就不会有问题。只要任何外部状态在被读取时保证是不可变的,就不会有任何问题。
回答by chrylis -cautiouslyoptimistic-
When a method is called, the JVM creates a stack framefor the call in the executing thread. This frame contains all of the local variables declared in the method. In the case of any method, static or otherwise, that doesn't access fields, each execution proceeds completely independently on each thread. If the method uses parameters in its calculation, these parameters are also located in the stack frame, and multiple calls don't interfere with each other.
当一个方法被调用时,JVM 会为正在执行的线程中的调用创建一个堆栈帧。该框架包含方法中声明的所有局部变量。在任何不访问字段的静态或其他方法的情况下,每个执行都在每个线程上完全独立地进行。如果方法在其计算中使用参数,这些参数也位于堆栈帧中,多次调用不会相互干扰。
回答by Eyal Schneider
The fact the method is static is irrelevant. They question should be what state variablesare being manipulated by the code in question.
该方法是静态的这一事实无关紧要。他们的问题应该是相关代码正在操纵哪些状态变量。
- If no members of any instance/class are read/written, then there should be no problem.
- In the case of write operations, synchronization of some kind is needed
- If there are only reads, it doesn't necessarily mean the method is well synchronized. It depends on how the data is being written and by which thread. If for example the code reads V which is protected by a monitor M during the write operation, then the reads of V must synchronize on the same monitor as well.
- 如果没有任何实例/类的成员被读/写,那么应该没有问题。
- 在写操作的情况下,需要某种同步
- 如果只有读取,并不一定意味着该方法同步良好。这取决于数据的写入方式和线程。例如,如果代码在写操作期间读取受监视器 M 保护的 V,则 V 的读取也必须在同一监视器上同步。
回答by wypieprz
If the two statements are executed in separate threads, there's no guarantee that the first thread changes will be visible to the second thread unless you establish a happens-beforerelationship between these two statements by synchronizing someMethod()
using a given synchronization strategy. In other words, your logic can give unexpected and unpredictable results if you are writing to the same variable(s) and then reading from two threads simultaneously.
如果这两个语句在单独的线程中执行,则无法保证第一个线程的更改对第二个线程可见,除非您通过使用给定的同步策略进行同步,在这两个语句之间建立了happens-before关系someMethod()
。换句话说,如果您写入相同的变量然后同时从两个线程读取,您的逻辑可能会产生意外和不可预测的结果。