繁体   English   中英

如何阻塞当前线程直到用户调用特定方法?

[英]How to block current thread until user calls a specific method?

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

  • onJobComplete()
  • onJobError(Throwable t)

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

这可以通过CountDownLatch(1)吗? (当这两种方法中的任何一种被调用时,我都会递减)。 似乎我只能将CountDownLatch线程一起使用。

如果没有,我怎样才能做到这一点?

背景: https : //github.com/ReactiveX/RxJava/issues/5094 (我需要从 3rd 方库异步使以下同步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()返回)。

使用锁定和条件的示例。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM