【问题标题】:Print odd and even using two threads in Java在Java中使用两个线程打印奇数和偶数
【发布时间】:2014-12-09 01:30:54
【问题描述】:

我正在尝试使用如下所示的两个线程来执行此操作。有人能指出我在这里犯的明显错误吗?

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 应该唤醒、打印并将 available 设置为 false。我不明白这里出了什么问题?我看到了其他解决方案,但想知道为什么我的解决方案不起作用。

【问题讨论】:

标签: java multithreading static java-threads


【解决方案1】:

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

的语法糖
public void printOdd() {
    synchronized(this) {
        ...
    }
}

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

【讨论】:

  • 啊...这就是为什么我需要创建一个对象并将其传递给两个线程进行操作。
猜你喜欢
  • 2013-05-17
  • 2019-03-17
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多