在java中进行同步的同步通信

时间:2014-08-01 14:40:09

标签: java multithreading synchronization wait notify

我想开发一个包含两个线程thread1和thread2的应用程序。 线程1必须打印最多50个偶数,线程2必须打印奇数到50。 并且两个线程都应该通信,使得印刷者应该是1,250。 我尝试了以下代码。 如何在EvenThread和OddThread之间进行通信

public class TestPrint{
    public static void main(String[] args) {
        EvenThread et=new EvenThread();
        OddThread ot=new OddThread();
        et.start();
        ot.start();
    }
}

class EvenThread extends Thread{
    int even=0;
    @Override
    public void run() {
        synchronized(this){
            while(even<50){
                System.out.println(even);
                even=even+2;
                try {
                    this.wait();
                    notify();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class OddThread extends Thread{
    int odd=1;
    @Override
    public void run() {
        synchronized(this){
            while(odd<50){
                System.out.println(odd);
                odd=odd+2;
                try {
                    this.wait();
                    notify();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您的线程需要使用相同的锁。在您的代码中,您的两个线程中的每一个都有自己的锁,因为这两个线程是使用synchronized(this)的单独对象。这意味着他们不等待轮流,当线程调用notify或notifyAll时它们不会得到通知(因为只有在同一个锁上等待的线程才收到通知)。

将锁对象添加到TestPrint类中,如下所示:

public static final Object LOCK = new Object();

让你的线程通过将其同步块更改为

来将其用作锁定
synchronized(LOCK) {

另外,在调用wait之后调用notify的方式也没有意义。您需要在写完条目后使用notify,并在等待有机会写入时等待。你需要有一些标志(例如TestPrint类中的一个volatile变量),线程用它来决定它们何时可以行动,在确定何时采取行动时单独依赖通知是不安全的(因为线程可以从等待返回)没有得到通知)。

假设您向TestPrint添加了另一个字段,以保存要打印的下一个值:

public static int nextValue = 1;

然后OddThread可以有如下代码:

try {
    synchronized(TestPrint.LOCK) {
        // wait for nextValue to become odd
        while (TestPrint.nextValue % 2 == 0) {
            TestPrint.LOCK.wait();
        }
        // at this point oddthread has the lock,
        // and nextValue is odd
        System.out.println(TestPrint.nextValue);
        TestPrint.nextValue += 1;
        // tell the other thread it can proceed
        TestPrint.LOCK.notify();
    }
} catch (InterruptedException e) {
    // won't happen (no one is calling interrupt
    // on this thread)
}

有关使用wait和notify的示例,请参阅section of the Oracle tutorial that discusses guarded blocks