Java并发-synchronized方法不起作用

标签 java multithreading concurrency

好吧,我现在正在与 java 并发作斗争,我有同步问题。我在堆栈上读了很多问题,但这里什么也看不到。

Class Checker 检查X 类的值。它应该始终是偶数(2,4,6,8 ...)

类 X 包含由 Checker.class 检查的X提供了increment方法,该方法应将X.classvalue加2

Y它只负责调用X.classinc()方法

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,无需任何同步。因此,您不能对它的值(value)抱有任何期望。

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

关于Java并发-synchronized方法不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22823672/

相关文章:

java - 缩放 View 以适应屏幕旋转/模拟 onScale() 方法

消费者-生产者。没有错误。有时工作。为什么?

javascript - NodeJS : Get Current VM Context

c# - 跨作用域 DbContext 的并发

c# - 在更新排序和显示时在并发字典中获取参数异常

java - 不可变但可刷新的集合?

Java为什么销毁对象后finalize方法不工作?

java - 新手javac导入库(httpclient)命令行

Java BufferedWriter.wite(string str) 在写入不存在的文件时不抛出 IOException

c++ - 有没有办法在 libstdc++ 中制作原子 shared_ptr?