簡體   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