在Java中使用两个线程打印奇数和偶数 [英] Print odd and even using two threads in Java

查看:162
本文介绍了在Java中使用两个线程打印奇数和偶数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to do it using two threads like below. Can someone point the obvious mistake I am doing here?

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.我不明白这里出了什么问题?我看到了其他解决方案,但想知道为什么我的解决方案无法正常工作.

But this program is only printing 1 and quitting. After printing 1 the available should be true and printEven should wake up, print and set available to false. I don't understand what is going wrong here? I saw other solutions but want to know why my solution is not working.

推荐答案

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

Putting synchronized on an instance method means that the thread calling that method has to acquire the lock on that instance; public void synchronized printOdd() is syntax sugar for

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

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

where this is different for each instance, since ThreadOdd and threadEven are two different objects and each one uses its own lock. The methods notifyAll and wait are called on the object that is being used as the lock. When one thread waits it never gets notified because the notification only applies to other threads waiting on the same lock as the notifying thread.

这篇关于在Java中使用两个线程打印奇数和偶数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆