2016-05-24 19 views
2

特定の要求を処理している第三者内部ライブラリを使用しようとしています。残念ながら、それは事実上同期的です。また、私は同じコードのコントロールがありません。基本的には関数呼び出しです。この関数は動作が少し不規則に見えます。この関数は処理を完了するのに10ミリ秒かかり、場合によっては要求を処理するのに最大300秒かかります。Javaで関数呼び出しを中断する方法

関数がx ms/secで処理を完了しなかった場合に中断された例外をスローするように、この関数の周りにラッパーを書く方法を提案できますか?私は結果が得られずに生きていき、処理を続けることができますが、3分の遅延を許容することはできません。

PS:この関数は、内部的にJMSを使用して別のシステムに更新を送信し、そのシステムが応答し、別の計算から離れて送信されるのを待ちます。

+0

は、スレッドを使用してメソッドを呼び出すと、時間のX量の後にスレッドを殺しますか? –

+2

彼は同期していると言っています...それは簡単ではありません...タイムアウトをサポートしていない場合は、ライブラリ自体のコードを変更する必要があります。 –

+0

Executorsインタフェースを見て、あなたの関数を別のスレッドで起動して、waititterminationのような時間制限メソッドを使用してください。詳細はこちら:https://docs.oracle。 – jaroslawj

答えて

3

この関数の周りにラッパーを記述して、関数がx ms/secで処理を完了しないと中断された例外をスローする方法を提案できますか?

これはできません。 InterruptExceptionは特定のメソッドによってのみスローされます。確かにthread.stop()と呼ぶことができますが、これは推奨されておらず、いくつかの理由で推奨されていません。

あなたのコードが一定時間応答を待つだけで、うまくいかない場合は、呼び出しを放棄する方がよいでしょう。たとえば、Callableを実際に「第三者内部ライブラリ」を呼び出すスレッドプールに送信できます。その後、メインコードは特定のタイムアウトを持つ​​を実行します。

// allows 5 JMS calls concurrently, change as necessary or used newCachedThreadPool() 
ExecutorService threadPool = Executors.newFixedThreadPool(5); 
... 
// submit the call to be made in the background by thread-pool 
Future<Response> future = threadPool.submit(new Callable<Response>() { 
    public Response call() { 
     // this damn call can take 3 to 3000ms to complete dammit 
     return thirdPartyInternalLibrary.makeJmsRequest(); 
    } 
}); 
// wait for some max amount of time 
Response response = null; 
try { 
    response = future.get(TimeUnit.MILLISECONDS, 100); 
} catch (TimeoutException te) { 
    // log that it timed out and continue or throw an exception 
} 

この方法の問題点は、あなたがコントロールの上の多くを持っていないリモートのJMSの問い合わせに対応するためのライブラリを待っているスレッドの全体の束を生む可能性があるということです。

簡単な解決策はありません。

0

これは第三者であるため、コードを変更することはできません。あなたは2つのことをする必要があります。

  1. 新しいスレッドで実行を開始します。
  2. タイムアウトを指定して現在のスレッドで実行を待機します。

可能な方法の1つは、セマフォを使用することです。

final Semaphore semaphore = new Semaphore(0); 
    Thread t = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      // do work 
      semaphore.release(); 
     } 
    }); 

    t.run(); 
    try { 
     semaphore.tryAcquire(1, TimeUnit.SECONDS); // Whatever your timeout is 
    } catch (InterruptedException e) { 
     // handle cleanup 
    } 

上記の方法は総ですが、私は可能な場合は、タイムアウトして、専用のワーカーキューまたはRxJavaを使用するように最新デザインをupdateing代わりにお勧めします。

0

ラムダは、割り当てられた時間内に完了しない場合、これはTimeoutExceptionがスローされます。

CompletableFuture.supplyAsync(() -> yourCall()).get(1, TimeUnit.SECONDS) 
+0

ありがとうございます。私はこれを試したところ、これはうまくいくようです。残念ながら、現在Java 1.7を使用しているため、これらの機能を十分に活用することはできません。しかし、答えをありがとう。私たちのアプリのためのJava 1.8のために推進する別の理由。 –

+0

また、私はStackOverflowを初めて使用しており、そのための特権を持っていないため、投票アップできません。 –

関連する問題