Java并发 - 同步方法不起作用

时间:2014-04-02 21:41:40

标签: java multithreading concurrency

好吧,我现在正在与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线程都在同一个对象上运行,这意味着它们应该是同一个锁吗?为什么这里的并发失败?我错过了什么?

1 个答案:

答案 0 :(得分:4)

您直接访问X.value,没有任何同步。因此,你不能期待它的价值。

引入同步getValue()方法,并从Checker调用此方法,以获得您期望的行为。