了解多线程等待并通知

时间:2017-11-30 08:35:01

标签: java multithreading

我正在学习多线程,我正在尝试了解如何使用Object类的wait和notify方法。我已经浏览了这个链接https://www.journaldev.com/1037/java-thread-wait-notify-and-notifyall-example,并编写了以下程序

服务员

public class Waiter implements Runnable {
    private Message m;
    public Waiter(Message m) {
         this.m = m;
    }
    public void run() {
        String name = Thread.currentThread().getName();
        System.out.println(t1 + " thread waiting for message");
        synchronized (m) {
            try {
                m.wait();
                System.out.println(t1 + " " + m.getText());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(t1 + " thread waiting for message");
    }
}

通告

public class Notifier implements Runnable {
    private Message m;
    public Notifier(Message m) {
         this.m = m;
    }
    public void run() {
        synchronized (m) {
            try {
                Thread.sleep(2000);
                m.notifyAll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

测试

public class WaitNotifyTest {
    public static void main(String[] str) {
        Message m = new Message("hello");
        new Thread(new Waiter(m), "t1").start();
        new Thread(new Waiter(m), "t2").start();
        new Thread(new Notifier(m)).start();
    }
}

当我执行程序时,它有时会正常终止,有时会无限期地等待,有时一个线程终止而另一个无限期地等待。谁能告诉我这里有什么问题?

另外,我想了解一些等待和通知方法的实时应用示例。

1 个答案:

答案 0 :(得分:1)

当你在做等待时,最好的做法是在一个带有条件的while循环中进行。可能有线程将通知的情况,然后其他线程进入等待状态。所以线程将始终处于等待状态

修改后的代码:

public class Waiter implements Runnable {
    private Message m;

    public Waiter(Message m) {
        this.m = m;
    }

    public void run() {
        String name = Thread.currentThread().getName();
        System.out.println(name + " thread waiting for message");
        synchronized (m) {
            try {
                while (m.getText() == null) {
                    m.wait();
                }
                System.out.println(name + " " + m.getText());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(name + " thread waiting for message");
    }
}

public class Notifier implements Runnable {
    private Message m;

    public Notifier(Message m) {
        this.m = m;
    }

    public void run() {
        synchronized (m) {

            m.setText("hello");
            m.notifyAll();

        }
    }
}

public class WaitNotifyTest {
    public static void main(String[] str) {
        Message m = new Message();
        new Thread(new Waiter(m), "t1").start();
        new Thread(new Waiter(m), "t2").start();
        new Thread(new Notifier(m)).start();
    }
}