2009-05-28 6 views
6

私はいくつかのサードパーティのライブラリを使用して、非同期プロトコル経由でサーバーに接続し、応答を返します。たとえば、ユーザー名でユーザーIDを取得する方法は次のようになります。Javaのコールバックと匿名クラスの助けが必要

public int getUserid(String username) { 
     int userid = 0; 

    connection.call("getUserid", new Responder() { 
     public void onResult(final int result) { 
      System.out.println("userid: " + result); 
      //how to assign received value to userid and return it? 
     } 
    }, username); 

    //wait for response 
    while (userid == 0) { 
      try{ 
       Thread.sleep(100); 
      } catch (Exception e) {} 
     } 


     return userid; 
} 

問題は、私は(後にそれを返すために)メソッドから変数を「USERID」するために、サーバの応答から返された「結果」を割り当てることができないです。これを解決するには?私はおそらくメソッドの変数ではなく、いくつかのクラス変数に割り当てることができますが、私は同時実行性の問題に対処する必要はないので、メソッドのスコープ内に保持したい。

ありがとうございました。

答えて

2

私があなたの質問を正しく理解していれば、匿名クラスの中から変数を書く方法を尋ねるでしょう。

匿名クラスは最終変数にのみアクセスでき、直接変数にアクセスすることはできません。

"十分に良い"簡単な解決策は、単一の値フィールドとゲッターとセッターでValueBoxクラスのソートを作成することです。関数内の新しい変数を最終変数としてインスタンス化し、匿名クラスにアクセスさせることができます。匿名クラスはgetterとsetterを使用して書き込み/読み取りを行います。

変数がfinalであるという事実は、他の場所で参照することはできませんが、参照されたオブジェクトの内容はどちらの関数からでも変更できます。

あなたが持っているより大きな問題は、コールバックが呼び出されるまで待つことです。この種の待機睡眠は十分かもしれませんが、達成しようとしていることに応じて、タイムアウト、スレッドなどを考慮する必要があります。

さらに、これは接続でこれを2回も呼び出さないことを前提としています。それ以外の場合は、同期モデルで詳細情報を提供する必要があります。

public int getUserid(String username) { 
     final ValueBox<Integer> userid = new ValueBox<Integer>(); 

     connection.call("getUserid", new Responder() { 
       public void onResult(final int result) { 
         System.out.println("userid: " + result); 
         userId.setValue(result); 
         //how to assign received value to userid and return it? 
       } 
     }, username); 

     //wait for response 
     while (userid.isEmpty()) { 
       try{ 
         Thread.sleep(100); 
       } catch (Exception e) {} 
     } 

     return userid.getValue(); 
} 
+0

ありがとうございました。しかし、これを複数回呼び出す必要があります...このValueBoxオブジェクトから読み取ったり書き込んだりするシンクロナイズモデルは何ですか?かなり複雑になるでしょう... – serg

+0

問題は、userIdを処理する前にgetUserIdを複数回呼び出すことができます(たとえば、最初の100msで5回の呼び出しがあったとします)。あなたは物事を上書きする危険性があります。そのような状況で何をしたいですか? – Uri

+0

現在のリクエストが完了するまで、それ以上のリクエストは処理しない可能性があります。 – serg

0

最も簡単な変更がjava.util.concurrent.SynchronousQueueのようなものを使用することです:

はここにいくつかのサンプルコードです。しかし、イベントドリブンインターフェイスを自分で提供したいと思うかもしれません。

関連する問題