调用等待和通知的两个线程 [英] Two thread which invokes wait and notify

查看:63
本文介绍了调用等待和通知的两个线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我见证的代码无法正常工作.

The code I've witten doesn't work as I expected.

static Integer sync = 1;

    static void m() throws Exception {
        synchronized (sync) {
            System.err.println("First");
            sync.notify();
            sync.wait(1000L);
            System.err.println("Second");
            System.err.println("Third");
        }
    }

    public static void main(String[] args) throws Exception {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    m();
                } catch (Exception ex) {
                    Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
        Runnable t = new Runnable() {
            @Override
            public void run() {
                try {
                    m();
                } catch (Exception ex) {
                    Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
        Thread th1 = new Thread(r);
        Thread th2 = new Thread(t);
        th1.run();
        th2.run();
   }

我们有两个线程执行m()的syncjronized语句.当第一个线程执行一个并遇到wait()时,它将被添加到等待集中.此后,第二个线程开始执行同步语句,并执行notify().由于输出必须为

We have two threads which execute m()'s syncjronized statement. When the first thread executes one and come across the wait() it'll be added to the wait set. After this, the second thread is starting to execute the synchronized statement, and perform notify(). Since the output must be

First
First
....

但实际上是

First
Second
Third
First
Second
Third

为什么?

推荐答案

首先,您的程序未创建任何线程.您必须调用th1.start()和th2.start()来创建线程.

First of all, your program is not creating any threads. You must call th1.start() and th2.start() to create threads.

t.start()是库提供的一种方法,可在您想启动线程时调用您的代码. run()是您为库提供的用于调用新线程中的 in 的方法.您的run()方法定义线程将执行的操作. IMO,run()是一个真正令人误解的名称.

t.start() is the method that the library provides for your code to call when you want to start a thread. run() is the method that you provide for the library to call in the new thread. Your run() method defines what the thread will do. IMO, run() was a really misleading name.

第二,notify()和wait()并没有像您认为的那样做.特别是,如果sync.wait()中当前没有其他线程,则sync.notify()根本不会执行任何操作.

Second, notify() and wait() don't do what it looks like you think they will do. In particular, sync.notify() will not do anything at all if there are no other threads currently in sync.wait().

使用notify()和wait()的正确方法是,一个线程执行此操作:

The correct way to use notify() and wait() is, one thread does this:

synchronized(lock) {
    while (! someCondition()) {
         lock.wait()
    }
    doSomethingThatRequiresSomeConditionToBeTrue();
}

另一个线程执行此操作

synchronized(lock) {
    doSomethingThatMakesSomeConditionTrue();
    lock.notify();
}

使用此模式时,除了从synced(lock)块内部,任何线程都不得更改someCondition()的结果.

When you use this pattern, no thread should ever change the result of someCondition() except from inside a synchronized(lock) block.

这篇关于调用等待和通知的两个线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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