0

スレッドで作成されたハンドラーにアクセスしているときに、null ポインター例外が発生することがあります。

私は2つのアプローチを使用しています。

1 つはスレッドを使用したサービスで、ハンドラーを作成し、サービス メソッドでアクセスします。2つ目は、アクティビティで作成されたスレッドで、スレッドを作成し、開始し、ハンドラーを作成しています。

問題は非常に単純です。ハンドラーはメインスレッドに対して非同期で作成されます。そして、私はメイン(GUIスレッド)でアクセスしているので、作成することもあれば、取得時にnullになることもあります。

私はGUIスレッド while(handler == null){ } で作ることができましたが、それは本当に悪い解決策です。これを行うエレガントな方法を探しています。

すべてがメインスレッドにあります。

Thread t = new Thread(new Runnable {
Looper.prepare();
handler = new Handler();
Looper.Loop();
}
handler.post(new Runnable{}) //at this point sometimes handler is still null. 
and it is created like few ms later. But still at this point i need valid handler
to background thread
4

2 に答える 2

0
  1. 「hander」属性が volatile でない限り、while ループまたはスリープを使用することは、洗練されていないだけでなく、間違っています。ハンドラーが null ではないことがわかったとしても、それを使用することはできません。ハンドラーへの書き込みとハンドラー インスタンスの作成の間には発生前の関係がないため、メイン スレッドはハンドラーへの参照を BEFORE ITS CONSTRUCTOR IS RUN と見なす可能性があります。

  2. 単純な参照を渡すための安全な選択は SynchronousQueue です (実際にはキューではなく、内部容量はなく、スレッド間でオブジェクトを移動するためだけに存在します)。あなたはそれを次のように使用します(私の頭から離れて、いくつかのタイプミスの可能性が非常に高いです):


    final SynchronousQueue<Handler> giveMeHandler = new SynchronousQueue();
    new Thread(new Runnable(){
       public void run(){
          Handler handler;
          // create a Handler;
          giveMeHandler.put(handler); // blocks until handler taken;
       }

    }).start();

    Handler handler = giveMeHandler.take(); // blocks until handler given
于 2012-04-19T15:17:06.683 に答える
0

Java ソースの並行パッケージを使用できます。可能な解決策:

これらは、同期ロジックをカプセル化します。

コードは次のようになります。

CyclicBarrier cb = new CyclicBarrier(2);
...
T1:
cb.await();
T2:
cb.await();

CyclicBarrier (または CountDownLatch) は、指定された数 (この場合は 2) のスレッドがバリアを待機するまで待機します。

于 2012-04-19T12:36:22.843 に答える