2016-04-04 22 views
1

これは基本的な質問である場合私の無知を許してください。バックグラウンド処理java

モジュールから制御を戻してバックグラウンドで処理を開始するにはどうすればいいですか?

コンポーネントAはコンポーネントBを呼び出します。コンポーネントBは基本的な処理を行い、バックグラウンドスレッドを開始し、すぐに制御をAに返します。バックグラウンドスレッドが処理を完了するたびに、結果を永続ストアに保存します。このバックグラウンドスレッドによる全体の処理は時間がかかり、バックグラウンドスレッドが終了するまで待つことはできません。

Component A { 
    Http Call component B 
} 

Component B { 
    // Got request from component A 
    start background thread(); 
    return; // don't wait till background thread finishes off 
} 

background thread() { 
// time consuming task 
} 

どのようにしてこの動作をJavaで達成できますか?私は、通信がタイムアウト設定を持つHTTP接続上で起こっているので、それが完全に非同期の処理形式ではないとは思わない。

更新:

Component A: 
Receives Http call 


Component B: 

Approach1: 

Runnable runnable = new MyThread(); 
new Thread(runnable).start(); 

Approach2: 

ExecutorService exec = Executors.newSingleThreadExecutor(); 
exec.execute(new MyThread()); 
exec.shutdown(); 

上記のアプローチの両方がバックグラウンド処理が完了する前に、HTTP呼び出しを返すようにしたいと仮定すると、バックグラウンド処理を開始し、A.

+0

あなたは並行性ユーティリティを見ましたか?そうでない場合は、ここをクリックしてください。https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html – Bajal

答えて

1

使用スレッドが概念のいくつかの簡単な証明のために良い解決策ですが、私少なくともJavaからの同時APIを使用しようとすることを強くお勧めします。文書hereを見つけることができます。良いチュートリアルはhere

最も簡単な方法は、実行したい命令を含むCallableオブジェクトを作成することです。

Callable myInstructions = new Callable<ObjectToReturn>() { 
     public ObjectToReturncall() { 
      return object.methodCall(); 
     }} 

ExecutorServiceを使用すると、Futureableオブジェクトが必要です。

Future<ObjectToReturn> future = executor.submit(myInstructions); 
//Do anything else as this wont be blocked .. 

将来のAPIには、タスクが既に完了しているかどうかを確認するための一連のメソッドがあります。

if(future.isDone()) // Ask if the task is done 
    ObjectToReturn solution = future.get() // Get the result 

非常に使いやすい未来API

EDIT

あなたは将来、APIからの応答を期待してはいけない場合は、ちょうどあなたが結果を受け取るか、応答を取得したいいけない場合、あなたが

Future<Void> future = executor.submit(new Callable<Void>() { 
    public Void call() throws Exception { 
     testA.abc(); 
     return null; 
    } 
}); 

その他のオプションを使用することができ、操作を行います、スレッドを起動するだけです

ExecutorService executor = Executors.newFixedThreadPool(5);` 
executor.execute(new RunnableClass()); 

ExecutorServiceのコールシャットダウンも避けてください。プロセスが終了したときに、春またはコンテナfwksでコンテナがシャットダウンを担当しているときに、ExecutorServiceアプリケーションがシャットダウンされた後

+0

ご回答ありがとうございます。やってみます。 – user3505394

+0

ねえ、私は上記の両方のアプローチを使ってこれを実装することができました。これが正しいことなのかどうかをお聞かせください。私は結果を得たいと思うので、コール可能を使用していません。 – user3505394

+0

また、エグゼキュータサービスのシャットダウンを呼び出すのが正しいかどうかはわかりません。私のコンポーネントAはhttpコールを複数回受け取るので、コールを取得し、executorerviceをシャットダウンするたびに、処理のために1つのバックグラウンドスレッドを開始します。また、コンポーネントAも同様にコールを取得できます。 – user3505394

0

に即時制御を戻すために私を助けましたあなたの疑似コードはJavaに対して完全に有効です。

次の詳細レベルでは、Thread,Runnablejava.nioのライブラリクラスのJavadocをチェックしてください。

0

最も簡単な方法は、バックグラウンド処理ロジックをパラメータとして新しいJava Threadを作成することです。 Javaのそれ以降のバージョンで

void componentB() { 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      // Time consuming task. 
     } 
    }).start(); 
    // The method continues without stopping. 
} 

は、あなたも、この達成するために ForkJoinPool級を使用することができます。生のレベルで

public class Main { 

    private final ExecutorService executor = new ForkJoinPool(); 

    void componentA() { 
     componentB(); 
    } 

    void componentB() { 
     executor.execute(this::timeConsumingTask); 
     // The method continues without stopping. 
    } 

    private void timeConsumingTask() { 
     // Time consuming task. 
    } 
} 
関連する問題