Java - 等待 Runnable 完成

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34459392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 22:55:16  来源:igfitidea点击:

Java - Wait for Runnable to finish

javaandroidmultithreading

提问by ThrowAway43616

In my app, I have the following code running on a background thread:

在我的应用程序中,我在后台线程上运行以下代码:

MyRunnable myRunnable = new MyRunnable();
runOnUiThread(myRunnable);

synchronized (myRunnable) {
    myRunnable.wait();
}

//rest of my code

And MyRunnable looks like this:

MyRunnable 看起来像这样:

public class MyRunnable implements Runnable {
    public void run() {

        //do some tasks

        synchronized (this) {
            this.notify();
        }
    }
}

I want the background thread to continue after myRunnable has finished executing. I've been told that the above code should take care of that, but there are two things I don't understand:

我希望后台线程在 myRunnable 完成执行后继续。有人告诉我上面的代码应该解决这个问题,但有两件事我不明白:

  1. If the background thread acquires myRunnable's lock, then shouldn't myRunnable block before it's able to call notify() ?

  2. How do I know that notify() isn't called before wait() ?

  1. 如果后台线程获取了 myRunnable 的锁,那么 myRunnable 在能够调用 notify() 之前不应该阻塞吗?

  2. 我怎么知道在 wait() 之前没有调用 notify() ?

回答by Jiang YD

  1. myRunnable.wait()will release the lock of myRunnableand wait notify
  2. we always add a check before wait.

    //synchronized wait block
    while(myRunnable.needWait){
        myRunnable.wait();
    }
    
    //synchronized notify block
    this.needWait = false;
    myRunnable.notify();
    
  1. myRunnable.wait()将释放锁myRunnable并等待通知
  2. 我们总是在等待之前添加检查。

    //synchronized wait block
    while(myRunnable.needWait){
        myRunnable.wait();
    }
    
    //synchronized notify block
    this.needWait = false;
    myRunnable.notify();
    

回答by Gediminas Rimsa

You could also use JDK's standard RunnableFuturelike this:

你也可以像这样使用 JDK 的标准RunnableFuture

RunnableFuture<Void> task = new FutureTask<>(runnable, null);
runOnUiThread(task);
try {
    task.get(); // this will block until Runnable completes
} catch (InterruptedException | ExecutionException e) {
    // handle exception
}

回答by Buddy

  1. The lock is released when the wait starts
  2. That's a possibility, you can avoid it by putting the runOnUiThreadwithin the synchronizedblock too (so that the runnable can't acquire the lock until the other thread is already waiting)
  1. 等待开始时释放锁
  2. 这是有可能的,你可以通过将避免它runOnUiThread的内synchronized块太(这样直到另一个线程已经等待可运行不能获得锁)

回答by mr.icetea

Create an Objectcalled lock. Then after runOnUiThread(myRunnable);, you can call lock.wait(). And when your myRunnableis finish it's job, call lock.notify(). But you must declare MyRunnableas inner class, so they can share the lockobject.

创建一个Object名为lock. 之后runOnUiThread(myRunnable);,就可以打电话了lock.wait()。当您myRunnable完成它的工作时,请致电lock.notify()。但是你必须声明MyRunnable为内部类,这样他们才能共享lock对象。