【问题标题】:interthread communication with synchronization in javajava中同步的线程间通信
【发布时间】:2014-08-01 14:40:08
【问题描述】:

我想开发一个包含两个线程thread1 和thread2 的应用程序。 线程 1 必须打印最多 50 的偶数,线程 2 必须打印最多 50 的奇数。 并且两个线程都应该进行通信,以便打印顺序应该是 1,2,50。 我尝试了以下代码。 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();
                }
            }
        }
    }
}

【问题讨论】:

  • 如果需要按顺序执行,为什么还要同时执行它们?

标签: java multithreading synchronization wait notify


【解决方案1】:

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

像这样向您的 TestPrint 类添加一个锁定对象:

public static final Object LOCK = new Object();

并通过将同步块更改为

让您的线程将其用作锁定
synchronized(LOCK) {

您在调用 wait 后立即调用 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)
}

有关使用等待和通知的示例,请参阅 section of the Oracle tutorial that discusses guarded blocks

【讨论】:

    猜你喜欢
    • 2020-02-01
    • 2012-03-06
    • 1970-01-01
    • 2011-02-11
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 2013-05-12
    相关资源
    最近更新 更多