如何在用户调用特定方法之前阻止当前线程?

时间:2017-02-14 01:28:28

标签: java multithreading concurrency java.util.concurrent

我需要阻止当前线程,直到我调用以下两个方法之一(我创建)。

  • onJobComplete()
  • onJobError(Throwable t)

这些方法将从不同的线程调用。

这可能是CountDownLatch(1)吗? (当调用这两种方法中的任何一种时,我会减少)。似乎我只能将CountDownLatch主题一起使用。

如果没有,我该如何做到这一点?

后台:https://github.com/ReactiveX/RxJava/issues/5094(我需要从第三方库异步制作以下同步onRun()方法)

   /**
    * The actual method that should to the work.
    * It should finish w/o any exception. If it throws any exception,
    * {@link #shouldReRunOnThrowable(Throwable, int, int)} will be 
    * automatically called by this library, either to dismiss the job or re-run it.
    *
    * @throws Throwable Can throw and exception which will mark job run as failed
    */
    abstract public void onRun() throws Throwable;

更多信息:由于库限制,我无法控制onRun()何时启动。库需要此方法是同步的,因为它的完成会自动向库发信号通知“作业”已成功完成。我希望“暂停”onRun()并阻止它返回,启动我自己的异步线程,并在我的异步线程“恢复”onRun()(允许onRun()返回)完成。

1 个答案:

答案 0 :(得分:0)

使用锁定和条件的示例。

class YourJob {
    boolean markFinished = false;   // is the job explicitly marked as finished
    final Lock lock = new ReentrantLock();
    final Condition finished = lock.newCondition();

    public void onRun() {
        // your main logic

        lock.lock();
        try {
            while(!markFinished) {
                finished.await();
            }
        } finally {
            lock.unlock();
        }
    }

    public void complete() {  // the name onComplete is misleading, as onXxx is usually
                              // used as method to be implemented in template method
        lock.lock();
        try {
            complete = true;
            finished.signalAll();
        } finally {
            lock.unlock();
        }
    }
}

如果您使用的是旧版本的Java,或者更喜欢使用Object wait()并通知:

,则类似
class YourJob {
    boolean markFinished = false;   // is the job explicitly marked as finished

    public void onRun() {
        // your main logic

        synchronized (this) {
            while(!markFinished) {
                wait();
            }
        }
    }

    public synchronized void complete() { 
        complete = true;
        notifyAll();
    }
}

所以要使用它:

YourJob job  = new YourJob();
tellYourLibCallJobOnRun(job);   // job.onRun() invoked asynchronously

//..... doing something else
// if job.onRun() is invoked in background, it will be blocked waiting
// at the end

job.complete();   // job.onRun() will continue after this