首页 > 解决方案 > 计数器值在多线程中得到休息

问题描述

我试图在一个线程中打印奇数,在另一个线程中打印偶数。我尝试创建两个线程并在运行方法中打印它。

public class OddEven
{
    private final int MAX = 10;
    private static int counter = 0;
    private volatile boolean isOdd = true;

    public synchronized void printEven(int counter)
    {
        try {
            if (!isOdd) {
                System.out.println(Thread.currentThread().getName() + " " + counter);
                counter++;
                isOdd = true;
            }
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void printOdd(int counter)
    {
        if (isOdd) {
            counter++;
            System.out.println(Thread.currentThread().getName() + " " + counter);
            isOdd = false;
        }
        notifyAll();
    }

    public static void main(String[] args) {
        OddEven oddEven = new OddEven();

        Thread th1 = new Thread() {
            public void run() {
                while (OddEven.counter < oddEven.MAX) {
                    oddEven.printEven(OddEven.counter);
                }
            }
        };
        th1.setName("even -");
        th1.start();

        Thread th2 = new Thread() {
            public void run() {
                while (OddEven.counter < oddEven.MAX) {
                    oddEven.printOdd(OddEven.counter);
                }
            }
        };
        th2.setName("odd -");
        th2.start();
    }
}

但它正在无限地打印它,如下所示。

even - 0
odd - 1
even - 0
odd - 1
even - 0
odd - 1

标签: javamultithreading

解决方案


阅读:Java 是“按引用传递”还是“按值传递”?

  1. 你传入一个原语。counter++;仅在方法内部有意义,对外部世界没有影响。count指的是方法参数,而不是字段this.count

  2. 条件上没有适当的同步OddEven.counter < oddEven.MAX,因此可能会发生不同的事情。

我的建议是删除isOdd并当场检查。例如,

public synchronized void printEven() {
    if (counter % 2 != 0) {
        System.out.println(Thread.currentThread().getName() + " " + ++counter);
    }
}

推荐阅读