2017-02-14 18 views
-5

Мне нужно заблокировать текущий поток, пока не назову один из двух следующих методов (которые я создал).Как заблокировать текущий поток, пока пользователь не вызовет определенный метод?

  • onJobComplete()
  • onJobError(Throwable t)

Эти методы будут вызываться из другого потока.

Возможно ли это с CountDownLatch(1)? (который я бы уменьшил при вызове любого из этих двух методов). Кажется, я могу использовать только CountDownLatch с новинками.

Если нет, то как я могу это сделать?

фон: https://github.com/ReactiveX/RxJava/issues/5094 (мне нужно сделать ниже синхронной onRun() методом из 3 партии библиотеки асинхронных)

/** 
    * 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

Я бы эти два метода устанавливают логическое значение и run sleep до тех пор, пока переменная не изменится, или как насчет 'wait/notify'? –

+1

Итак, какова ваша «текущая тема»? Может ли вопрос быть более конкретным? 'wait' /' notify' (или 'await' /' signal') кажется чем-то, что вы можете изучить. Но есть и другие лучшие конструкции параллелизма, такие как «Будущее». Ваш вопрос слишком расплывчатый, чтобы люди предлагали –

+0

Определенно, используйте 'Future'. – dimo414

ответ

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() и уведомить:

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