好吧,我现在正在与java并发作斗争,我在同步方面遇到了问题。我在堆栈上阅读了很多问题,但在这里我看不到任何东西。
类 Checker
检查X
类的值。它应该始终是偶数(2,4,6,8 ...)
类 X 包含由 Checker.class
检查的value
。 X
提供了increment
方法,该方法应将 2 添加到value
X.class
类Y
它只负责调用inc()
X.class
方法
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Checks for concurrency fails
*
* @author Jones
*
*/
class Checker implements Runnable {
public Checker() {
new Thread(this).start();
}
@Override
public void run() {
while (true) {
if (X.value % 2 != 0){
System.out.println("Concurrency fail");
System.out.println(X.value);
}
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class X {
static Integer value = 0;
static synchronized void inc() {
value++;
Thread.yield(); // to accelerate probability of non concurrent
// behaviour
value++;
}
}
class Y implements Runnable {
X x;
public Y(X x) {
this.x = x;
new Thread(this).start();
}
@Override
public void run() {
while (true) {
x.inc();
try {
TimeUnit.MILLISECONDS.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) throws IOException {
X x = new X();
for (int i = 0; i < 5; i++) {
new Y(x);
}
new Checker();
}
}
我不明白为什么这里的并发失败。这应该是正确的。所有 Y 线程都在同一对象上运行,这意味着它们应该相同锁定?为什么这里的并发失败?我错过了什么?
您直接访问X.value
,无需任何同步。因此,您不能期望对其价值有任何期望。
引入一个同步的getValue()
方法,并从检查器调用此方法,以获得您期望的行为。