繁体   English   中英

Java并发同步不起作用

[英]Java Concurrency Synchronized not working

并发未按预期工作。

class Counter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}


public class Main {
    public static void main(String[] args) throws InterruptedException{
        Counter counter = new Counter();
        new Thread(() -> counter.increment()).start();
        new Thread(() -> counter.decrement()).start();
        System.out.println(counter.value());
    }
}

这个打印 1 而不是 0。我从 Oracle 教程中复制了这个示例,我不确定我错在哪里。

您不会等待线程完成。 所以你有机会,没有、两个或只有一个线程运行,所以你的结果可能是 -1、0 或 1。你应该使用 join() 来等待你的线程完成。

public void main(String[] args) throws InterruptedException{
    Counter counter = new Counter();
    Thread t1 = new Thread(() -> counter.increment());
    Thread t2 = new Thread(() -> counter.decrement());
    t1.start();
    t2.start();
    t1.join(); // waits for t1 to end processing
    t2.join(); // waits for t2 to end processing
    System.out.println(counter.value());
}

您还可以从 value() 中删除 synchronized,因为它不再用于任何异步进程。

您的主函数中的执行线程未链接到您的进程。 线程 2 可以在线程 1 之前运行,它们都可以在您的打印语句之后运行,反之亦然。 尝试重新执行您的主要不同时间并在运行函数中打印线程。 这可以帮助您更好地理解。 例如:

public static void main(String[] args) {
Counter counter = new Counter();

    new Thread(() -> {
        counter.increment();
        System.out.println("Thread-1 increment");
    }).start();
    new Thread(() -> {
        counter.decrement();
        System.out.println("Thread-2 decrement");
    }).start();
    System.out.println(counter.value());
}

在从线程获取结果之前,您需要在线程上使用 join。 此外,您还需要对将在异步线程中使用的每个方法使用同步,在本例中是它的增量和减量方法。

我做了一个例子,展示了没有同步添加到方法中会发生什么

class Counter {
    private int c = 0;

    public void increment() {
        c++;
    }

    public void decrement() {
        c--;
    }

    public int value() {
        return c;
    }
}


public class Main {
    public static void main(String[] args) throws InterruptedException {
        for (int j = 0; j < 10; j++) {
            Counter counter = new Counter();
            List<Thread> list = new ArrayList<>();
            for (int i = 0; i < 100000; i++) {
                list.add(new Thread(counter::increment));
                list.add(new Thread(counter::decrement));
            }

            for (Thread item : list) {
                item.start();
            }
            System.out.println("Results");
            System.out.println(counter.value());
            System.out.println(counter.value());
            System.out.println(counter.value());
            System.out.println(counter.value());
            System.out.println(counter.value());

            for (Thread item : list) {
                item.join();
            }

            System.out.println("Results after join");
            System.out.println(counter.value());
        }
    }
}

我确实运行了几次,有时甚至在使用 join 后结果 -3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM