2017-02-14 53 views
-5

我需要阻止當前線程,直到我調用以下兩種方法之一(我創建的)。如何在用戶調用特定方法之前阻止當前線程?

  • 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()返回),一旦我的異步線程完成。

+0

我會,如果你使用的是Java的舊版本或)更喜歡使用對象的wait(和通知

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(); } } } 

類似這兩個方法設置一個布爾值並且運行休眠直到變量發生變化,或者'wait/notify'怎麼樣? –

+1

那麼,你的「當前線程」在做什麼?問題可以更具體嗎? 'wait' /'notify'(或'await' /'signal')似乎是你可能會看到的東西。但也有其他更好的併發構造,比如'Future'。你的問題太模糊,人們建議 –

+0

當然,使用'未來'。 – dimo414

回答

0

使用鎖定和條件的示例。

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 
相關問題