簡體   English   中英

如何將帶有ReentrantLock的線程包裝到CompletableFuture調用中?

[英]How to wrap Thread with ReentrantLock into CompletableFuture call?

這是我當前的實現,它連續處理不同的文件讀取/保存操作:

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中。 如何在當前的實現中執行此操作?

您可以執行以下操作:

  • 您可以使用隊列,而不是將要完成的下一個作業存儲為在this.myThreadImpl鎖后進行更新的單個引用( 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 commons的ImmutablePair 。)

當需要處理東西時,阻塞隊列通常很有用: https : //docs.oracle.com/javase/8/docs/api/java/util/concurrent/BlockingQueue.html

另外,您是否看過ExecutorService 您可以使用基於單個線程的線程以串行方式執行作業:它的submit(Callable<> task)方法與上面定義的runThread()十分相似,因為它返回一個Future<Void> ,它將告訴您何時任務完成了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM