好吧,我现在正在与java并发战斗我遇到同步问题。我在堆栈上看了很多问题但是我在这里看不到任何东西。
类Checker
检查X
类的值。它应该始终是偶数(2,4,6,8 ......)
X类包含value
,由Checker.class
检查。 X
提供increment
方法,该方法应将value
X.class
添加2 {/ 1}}
班级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线程都在同一个对象上运行,这意味着它们应该是同一个锁吗?为什么这里的并发失败?我错过了什么?
答案 0 :(得分:4)
您直接访问X.value
,没有任何同步。因此,你不能期待它的价值。
引入同步getValue()
方法,并从Checker调用此方法,以获得您期望的行为。