2017-01-27 4 views
1

私は、クライアントにロジックを公開するHTTPコンポーネントを持つprojectAというプロジェクトを持っています。mongodb bsonライブラリを持つMongodbドライバは、別のプロジェクトで使用するとcompletableFutureがハングする

このプロジェクトの中で、このようなようなコードがあります:

void syncMethod() { 
    CompletableFuture<Void> f = new CompletableFuture<>(); 
    someAsyncOperationThatReceivesACallback((Void x, Exception ex) -> { 
    if(ex != null) f.completeExceptionally(ex); 
    else f.complete(null); // An example of a result. 
    }); 
    f.get(); // Wait unconditionally 
} 

そして、このコードは動作の完了を待って、将来は、非同期操作の結果を完了すると、動作します。

必要が2つのWebアプリケーション間のロジックを共有するために生まれたので、私はのはprojectA-LOGICprojectA-HTTP.dependsOn(projectA-LOGIC)

projectA-HTTPのエントリポイントとパッケージ化JARで上記のコードを持つprojectA-HTTPを言わせて、2つのプロジェクトにprojectAを分離projectA-LOGICのコードが完了しなくなりました。これは未来が決して完了せず、アプリケーションがただそこにあることを意味します。

しかし、私はprojectA-LOGICにエントリポイントを作成し、上のコードを実行するとすべてが機能します。

私はここで起こっている魔法を理解していません。現在jdk8_111を使用しています。上で抽象化された非同期操作はmongodb async driverから得られ、listCollectionNamesです。すべての非同期(コールバック経由)操作は、2つのプロジェクトがある場合、先物を使用して同期を行うと同じ動作になります。

EDIT:

スレッドダンプ:

全スレッドダンプ

"[email protected]" prio=5 tid=0x1 nid=NA waiting 
    java.lang.Thread.State: WAITING 
     at sun.misc.Unsafe.park(Unsafe.java:-1) 
     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
     at java.util.concurrent.CompletableFuture$Signaller.block(CompletableFuture.java:1693) 
     at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323) 
     at java.util.concurrent.CompletableFuture.waitingGet(CompletableFuture.java:1729) 
     at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895) 

"cluster-ClusterId{value='588bc56a32de912224244114', description='null'}-127.0.0.1:[email protected]" daemon prio=5 tid=0xf nid=NA waiting 
    java.lang.Thread.State: WAITING 
     at sun.misc.Unsafe.park(Unsafe.java:-1) 
     at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) 
     at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.waitForSignalOrTimeout(DefaultServerMonitor.java:238) 
     at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.waitForNext(DefaultServerMonitor.java:219) 
     at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:168) 
     - locked <0x10fe> (a com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x15 nid=NA waiting 
    java.lang.Thread.State: WAITING 
     at sun.misc.Unsafe.park(Unsafe.java:-1) 
     at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1037) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1328) 
     at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:277) 
     at com.mongodb.connection.BaseCluster$WaitQueueHandler.run(BaseCluster.java:464) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x14 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.Iocp.getQueuedCompletionStatus(Iocp.java:-1) 
     at sun.nio.ch.Iocp.access$300(Iocp.java:46) 
     at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:333) 
     at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x13 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.Iocp.getQueuedCompletionStatus(Iocp.java:-1) 
     at sun.nio.ch.Iocp.access$300(Iocp.java:46) 
     at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:333) 
     at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x12 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.Iocp.getQueuedCompletionStatus(Iocp.java:-1) 
     at sun.nio.ch.Iocp.access$300(Iocp.java:46) 
     at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:333) 
     at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x11 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.Iocp.getQueuedCompletionStatus(Iocp.java:-1) 
     at sun.nio.ch.Iocp.access$300(Iocp.java:46) 
     at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:333) 
     at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=5 tid=0x10 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.Iocp.getQueuedCompletionStatus(Iocp.java:-1) 
     at sun.nio.ch.Iocp.access$300(Iocp.java:46) 
     at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:333) 
     at java.lang.Thread.run(Thread.java:745) 

"[email protected]" daemon prio=8 tid=0x3 nid=NA waiting 
    java.lang.Thread.State: WAITING 
     at java.lang.Object.wait(Object.java:-1) 
     at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) 
     at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) 
     at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) 

"Reference [email protected]" daemon prio=10 tid=0x2 nid=NA waiting 
    java.lang.Thread.State: WAITING 
     at java.lang.Object.wait(Object.java:-1) 
     at java.lang.Object.wait(Object.java:502) 
     at java.lang.ref.Reference.tryHandlePending(Reference.java:191) 
     at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) 

"Attach [email protected]" daemon prio=5 tid=0x5 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 

"Signal [email protected]" daemon prio=9 tid=0x4 nid=NA runnable 
    java.lang.Thread.State: RUNNABLE 

私が理解することはできませんが、これは別々のプロジェクトにコードをsplitingによってだけ起こることができる方法です。 CompletableFuturesについての微妙な詳細が不足していると思ってください。

+0

私は実際に何ができるのかは分かりませんが、デッドロックを探します。また、共通スレッドプールのスレッドを使用しているものがないかどうかを確認します。 IIRC CompletableFuture共通プールのスレッドを使用する - 別個のプールを使用する可能性があります。 – john16384

+0

それは私が思うものです、スレッドダンプを追加しました。しかし、私は何が起こっているのか理解したいと思います。 – pedromss

+0

これがスレッドダンプの場合は、コードがまったく実行されていないと思われます.2つのJVMスレッドのみです。 – john16384

答えて

0

問題は、私が期待していたものよりはるかに簡単で(愚かな)ことが判明しました。

私はmongodb非同期ドライバv3.2.1を使用していましたが、mongodb bsonライブラリv3.4.1を使用していました。私がbsonライブラリのバージョンをv3.2.1に変更したとき、すべてうまくいきました。

関連する問題