繁体   English   中英

在Java中使用两个线程打印奇数和偶数

[英]Print odd and even using two threads in Java

我正在尝试使用下面的两个线程来做到这一点。 有人可以指出我在这里犯的明显错误吗?

public class OddEven {

public static boolean available = false;
public static Queue<Integer> queue = new LinkedList<Integer>();

static Thread threadEven = new Thread() {
    @Override
    public void run() {
        printEven();
    }

    public synchronized void printEven() {
        while (!available) {
            try {
                wait();
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        }

        System.out.println(queue.remove());

        available = false;
        notifyAll();
    }
};

static Thread threadOdd = new Thread() {
    @Override
    public void run() {
        printOdd();
    }

    public synchronized void printOdd () {
        while (available) {
            try {
                wait();
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        }

        System.out.println(queue.remove());

        available = true;
        notifyAll();
    }
};

public static void main(String[] args) {
    int n = 20;
    for (int i = 1; i < n; i++) {
        queue.add(i);
    }

    threadOdd.start();
    threadEven.start();

    try {
        Thread.sleep(60000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    try {
        threadOdd.join();
        threadEven.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

}

但是该程序仅打印1并退出。 在打印1之后,available应该为true,printEven应该被唤醒,将print设置为false。 我不明白这里出了什么问题? 我看到了其他解决方案,但想知道为什么我的解决方案无法正常工作。

将同步放在实例方法上意味着调用该方法的线程必须获取该实例上的锁; public void synchronized printOdd()是语法糖

public void printOdd() {
    synchronized(this) {
        ...
    }
}

其中, this是每个实例不同,因为ThreadOdd和threadEven是两个不同的对象,每个人用自己的锁。 在用作锁的对象上调用notifyAll和wait方法。 当一个线程等待时,它永远不会得到通知,因为该通知仅适用于与通知线程处于同一锁上的其他线程。

暂无
暂无

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

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