bod*_*ich 2 java multithreading
我在两个线程使用相同的方法时遇到了麻烦.
问题是:看起来当一个线程调用方法,并且方法正在运行,同时另一个线程尝试调用相同的方法时,Java只是跳过该调用!因此,当2个线程调用相同的方法时,该方法只被调用一次.因此,有时候随机编程只是跳过方法,代码根本不执行!怎么可能?在不同的机器上尝试,它的工作绝对不像预期,对我来说看起来像一个可怕的Java bug.
如果有任何专家会阅读本文,请说明发生了什么,如果已知问题,请给我解释的链接.谢谢!
PS:代码完全正常,你甚至可以将它粘贴到像repl.it或类似的在线java.在a.updateCounter(inc)之后; 我检查增量器是否工作(第45行).
class Main {
public static void main(String[] args) {
ThreadOne t1 = new ThreadOne(1000, 300, "Thread 1");
ThreadOne t2 = new ThreadOne(1, 300, "Thread 2");
Thread one = new Thread(t1);
Thread two = new Thread(t2);
one.start();
two.start();
}
}
class Accum {
private static Accum a = new Accum();
private int counter = 0;
private Accum() {}
public static Accum getAccum() {
return a;
}
public void updateCounter(int add) {
counter += add;
}
public int getCount() {
return counter;
}
}
class ThreadOne implements Runnable {
Accum a = Accum.getAccum();
int inc;
int max;
String threadName;
ThreadOne(int i, int c, String name) {
inc = i;
max = c;
threadName = name;
}
public void run() {
for(int x = 0; x < max; x++) {
int check = a.getCount();
a.updateCounter(inc);
if(check + inc != a.getCount()) System.out.println("\nupdateCounter was skipped at x " + x + "\nThread name: " + threadName);
try {
Thread.sleep(5);
} catch(InterruptedException ex) {
System.out.println("x: " + x + "\n ex: " + ex);
}
}
System.out.println(threadName + ": " + a.getCount());
}
}
Run Code Online (Sandbox Code Playgroud)
首先,Java不会跳过调用.这只是与您的测试不符的实际结果.
在int check = a.getCount();和测试之间if(check + inc != a.getCount()),计数器只是由另一个线程改变.就这么简单.
更新:操作counter += add不是ATOMIC,即您可以将其视为3个操作的序列:
counter读取的值counter现在想象两个线程在同一时间完全执行此序列,并且您理解为什么值不会增加.
使这个调用成为原子的解决方案:只需使用AtomicInteger@gudok提到的:
import java.util.concurrent.atomic.AtomicInteger;
public class Accum {
private static Accum a = new Accum();
private AtomicInteger counter = new AtomicInteger(0);
private Accum() {}
public static Accum getAccum() {
return a;
}
public void updateCounter(int add) {
counter.addAndGet(add);
}
public int getCount() {
return counter.intValue();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |