2016-09-29 14 views
0

これは、異なるファイルの読み取りを扱う私の現在の実装/連続操作を保存している:ReentrantLockでスレッドをCompletableFuture呼び出しにラップする方法は?

public void runThread(MyThreadImpl myThreadImpl) { 
    synchronized (this) { 
     this.myThreadImpl = myThreadImpl; 
     notify(); 
    } 
} 

synchronized public void run() { 
    while (true) 
     try { 
      wait(); 
      Global.myReentrantLock.lock(); 
      try { 
       try { 
        myThreadImpl.call(); 
       } catch (FileException e) { 
        // trace e 
       } catch (RuntimeException e) { 
        // trace e 
       } catch (Exception e) { 
        // trace e 
       } 
      } finally { 
       Global.myReentrantLock.unlock(); 
      } 
     } catch (InterruptedException e) { 
      // trace e 
     } catch (Exception e) { 
      // trace e 
     } 
} 

私は別の操作を実行する前に、スレッドの結果を待たない、と私はケースに来ている問題を抱えていますどこが必要ですか?

私はJava 8を使用しているので、これをCompletableFutureで囲みたいと思っていました。現在の実装ではどうすればいいですか?

答えて

1

次の操作を行うことができます:

  • 代わりにロックがフリーになると、キューを使用することができ、更新された単一の参照(this.myThreadImpl)として行われる次のジョブを格納します。
  • 新しいジョブが追加されると、新しいCompletableFutureが作成され、その参照が呼び出し元に返されます。
  • ジョブが完了すると、未来が完了します。

あなたのコードを更新し、queueはタイプQueue<Pair<CompletableFuture<Void>, MyThreadImpl>>のブロッキングキューであると仮定すると、あなたが持っているでしょう:

ここ
/** 
* @return a Future that will complete once the passed MyThreadImpl has been run. 
*/ 
public CompletableFuture<Void> runThread(MyThreadImpl myThreadImpl) { 
    Pair<CompletableFuture<Void>, MyThreadImpl> p = 
       new Pair<>(new CompletableFuture<>(),myThreadImpl); 
    queue.add(p); 
    return p.left; 
} 

public void run() { 
    while (true) { 
     try { 

      Pair<CompletableFuture<MyThreadImpl>, MyThreadImpl> p = 
        queue.take(); // will block until a job is added 

      try { 
       p.right.call(); 
       p.left.complete(null); // Future<Void> can only be completed with null. Alternatively, it could be completed with a relevant result. 
      } catch (Exception e) { 
       p.left.completeExceptionally(e); 
      } 

     } catch (InterruptedException e) { 
      // trace e 
     } 
    } 
} 

PairをちょうどペアのようなPOJOにする必要があります。 (これは、ApacheコモンズのImmutablePair、例えばである可能性があります。)

ブロッキングキューは、ものを処理する必要がある場合、一般的に便利です。またhttps://docs.oracle.com/javase/8/docs/api/java/util/concurrent/BlockingQueue.html

は、あなたがExecutorService見てきましたか? 1つのスレッドに基づいたジョブを使用して、ジョブを連続して実行することができます。submit(Callable<> task)のメソッドは、runThread()と非常によく似ています。これは、タスクが完了したときに通知するFuture<Void>を返します。

関連する問題