web-dev-qa-db-ja.com

スレッド間で情報を渡す最良の方法は何ですか?

私のプログラムが他のことをしている間、サーバーからメッセージを受信したときに、それを解釈したいのです。

私はスレッドについては知っていますが、それがどのように機能するかについては完全にはわかりません。サーバーをリッスンするスレッドがある場合、そのデータを解釈のためにメインスレッドに渡すにはどうすればよいですか?メインスレッドがサーバーにデータを送信する最良の方法は何ですか? synchronized修飾子の使用法は何ですか?

25
Bakies

サーバーをリッスンするスレッドがある場合、そのデータを解釈のためにメインスレッドに渡すにはどうすればよいですか?メインスレッドがサーバーにデータを送信する最良の方法は何ですか?

これには BlockingQueue を使用します。 BlockingQueue などの単一のLinkedBlockingQueueを定義します。次に、リスナークラスはqueue.take()を呼び出します。これは、サーバーがqueue.put()を呼び出すのを待機します。すべての同期、待機、通知などを、独自のコードではなくJavaクラスに残します。

Synchronized修飾子の使用法は何ですか?

これについてもっと理解するために、私は読書をします。これは、短めのSO応答。 Java並行性チュートリアル を開始するのに適した場所です。

33
Gray

メインスレッドと処理スレッド間の同期通信が必要な場合は、 SynchronousQueue を使用できます。

アイデアは、メインスレッドがput()を呼び出して処理スレッドにデータを渡し、処理スレッドがtake()を呼び出します。両方ともブロッキング操作です。

結果を送り返したい場合、メインスレッドが結果の準備ができたことを知る必要があるため、事態はもう少し複雑になる可能性があることに注意してください。 CountDownLatch はこれに適したプリミティブです。このようなことができます。

まず、データを渡すためのデータ構造を定義しましょう。

_public class MethodCall {

    public final String methodName;

    public final Object[] args;

    public final CountDownLatch resultReady;

    public Object result;

    public MethodCall(String methodName, Object[] args) {
        this.methodName = methodName;
        this.args = args;
        this.resultReady = new CountDownLatch(1);
    }

    public void setResult(Object result) {
        this.result = result;
        resultReady.countDown();
    }

    public Object getResult() throws InterruptedException {
        resultReady.await();
        return result;
    }
}
_

両方のスレッドから見える、データを渡すキューを定義します。

_public SynchronousQueue<MethodCall> methodCalls = new SynchronousQueue<MethodCall>();
_

メインスレッドから処理スレッドへの呼び出しを行い、結果を待つには:

_MethodCall call = new MethodCall(methodName, args);
methodCalls.put(call);
Object result = call.getResult();
_

run()メソッドなどの処理スレッドでは、次のことができます。

_for (;;) {
    MethodCall call = methodCalls.take();
    Object res = processStuff(call.methodName, call.args);
    call.setResult(res);
}
_

processStuffはロジックを実装します。もちろん、例外にも対処し、終了の場合に対処し、MethodCallを変更して、methodNameおよびargsおよびObjectリターンよりも具体的なものにする必要があります。など.

8

Javaスレッド。

http://www.journaldev.com/1079/Java-thread-tutorial

あなたの問題は生産者-消費者モデルのように思えます。BlockingQueueを使用してこのタスクを簡単に達成できます。

Javaブロッキングキュー

6
Pankaj