0

1. メイン UI スレッドがあり、ライブラリ関数を使用しています。

MainUI {
    library.funcA(1);
    library.funcB(2,3);
}

メインスレッドが各呼び出しの終了を待たないようにします。また、呼び出しごとに新しいスレッドを作成することは効果がなく、スレッドセーフではないため、別の同じスレッドで実行したいと考えています。そこで、単一のメッセージ キュー / ハンドラを持つ別のスレッドを作成しました。

MainUI {
    handler.post(new Message(FUNC_A,[1]));
    handler.post(new Message(FUNC_B,[2,3]));
}

しかし、毎回新しい Message オブジェクトを作成し、handleMessage() で再度デコードする必要があるというオーバーヘッドがあるようです。さらに、さまざまな数の引数のパック/アンパックを処理するのは見苦しく見えます。すべての関数を Runnable にしてハンドラーに投稿することを考えましたが、関数には異なる引数があり、Runnable クラスを拡張する新しいクラスを作成する必要があります。

私の現在の計画は、同期化されたキーワードをライブラリ内のすべての関数に挿入して、スレッドが 1 つずつ実行されるようにすることですが、多くのスレッドの作成/消滅が嫌いで、システムが重くなります (スレッドセーフでもありません)。意見が聞きたいです。

2. ライブラリが (メイン スレッドだけでなく) 多くのスレッドから呼び出される場合、呼び出しをライブラリ自体の単一スレッドで実行するように変換する最良の方法は何ですか?

4

2 に答える 2

0

次のように Runnable を使用できます。

int x = 1;
int y = 2;
//  "a" and "b" are here to show how variable values can be sent to funcB.
//  You could skip this and just have "funcB( 1, 2 )", of course.
final int  a = x;  
final int  b = y;
handler.post( new Runnable()  {
    public void run()  { library.funcB( a, b ); }
} );

ハンドラー ビットは少しトリッキーです。キューから各 Runnable を実行するには、ループ スレッドを実行する必要があります。次に、post物事をキューに入れるメソッドが必要です。何らかの形式のブロッキング キューは、2 つをリンクする最も簡単な方法であり、独自の Object.wait/Object.notify を実行する必要がなくなります。メソッドの同期は、post複数のスレッドが互いにつまずかないようにする最も簡単な方法です。

于 2012-07-17T19:21:45.393 に答える
0

私の意見では、現在のアプローチはスレッドセーフにするための実行可能なオプションです。ただし、Runnable をハンドラーに渡したい場合は、Runnable クラスをオーバーロードすることを検討できます。ここに疑似コードがあります

private Class MyRunner extends Runnable{
    public MyRunner(){
    //This is without any argument
    }

    public MyRunner(arg1){
    //This is with 1 argument
    }

    public MyRunner(arg1,arg2){
    //This is with 2 arguments
    }

}

それでも、MyRunner クラスのインスタンスが多数作成されます。

于 2012-07-17T01:34:06.353 に答える