- - PR -
Threadの一斉開始(完全同期)について
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-01-27 12:45
完全に同期したリクエストとは違うかもしれませんが、
Producer-Consumerのパターンを適用し、発行元がキューにリクエストをポストし、 Comsumerがリクエストを取り出し、すべてのスレッドに配信してやるというのはいかがでしょうか? 同一の発行時間で、同一のメッセージを投げることはとりあえず出来ます。 | ||||||||
|
投稿日時: 2005-01-27 18:09
物理的にはCPUが1つしかなければスレッドの実行は逐次処理になります。スレッドの 切り替えはOSがスケジューリングしますが、極短い処理(数ミリ秒以内)であれば スレッドの処理が完了してから次のスレッドにスケジューリングされると思われます。 取得する時刻については、System.currentTimeMillis()の場合、OSが利用している クロック割り込みの分解能に左右されます。システムにより分解能は変わりますが、 x86 Windows2000では10msまたは15msの分解能のようです。SPARC Solarisだと10ms または1msになります。 絶対時刻ではなく相対時刻でよい場合、J2SE 5.0(Tiger)のSystem.nanoTime()を 使うと分解能が良くなります。
論理的には、複数スレッドに処理開始を通知するなら、wait/notifyAll を使用する ことになります。 J2SE 5.0(Tiger)では、java.util.concurrentパッケージのCountDownLatchクラスを 使うと少し簡単に実現できます。ちょっとオーバーヘッドがかかりますが、同じ パッケージのExecutorServiceインタフェースのinvokeAllを使っても実現できます。 | ||||||||
|
投稿日時: 2005-01-27 19:24
一つのウェイトセットに集めてnotifyAllを使えば通知は(ほぼ)同時に出来るとは思いますが、その後起こされたスレッド群がロックの取り合いを始めませんか? まあ、すぐにsynchronized抜ければ誤差範囲だとは思いますが、一旦整列はしちゃいますよね。 むしろ、単純に共有オブジェクトの値を変化させてやるのがいいような気がします。
まあ、OSの都合やら何やらでCPUが物理的に複数積まれているからといって、Javaのマルチスレッドが本当にパラレルに動くかどうかとかにはまだ色々あるようですが…… http://www.idg.co.jp/lw/news/back/index20010824_01_solaris.html | ||||||||
|
投稿日時: 2005-01-28 02:23
非volatileな変数をスレッド間で共有する場合、変数の値の変更が即座に他のスレッドで 読み出せることは保証されません。各スレッドが作業コピーを持つことが許されており、 作業コピー間で同じ変数でありながら異なる値を取ることがあります。volatile宣言を するとスレッド間の整合性が保証されるはずですが、これはもしかするとJ2SE5.0(Tiger) 以降からの仕様かもしれません。(JSR-133の実装による)
Solarisの場合、Solaris9からは1:1モデルがデフォルトとなっているようです。 | ||||||||
|
投稿日時: 2005-01-28 11:17
ご指摘有り難うございます。 恥ずかしながら、volatileに関しては、マルチスレッドプログラミングでlongやdoubleが面白い値を返さないようにするために付けるもの……くらいの認識しかありませんでした。 スレッド毎の作業コピー……先に挙げた結城さんの本でその辺に言及している記述があった気もしますが……すっかり頭から抜け落ちてしまっていました。 | ||||||||
|
投稿日時: 2005-01-28 13:08
最近は1:1が再注目されてる感じですね。 AIXではM:Nがデフォルトだったと思いますが、プログラマに対して 「1:1のほうがパフォーマンスが良くなることが多いですよ」という アドバイスをしていたと思います。 NetBSDだとM:Nですが、こっちはM:Nだからどうこうというより、 SAはどうなんだ、という話になるでしょうか。 [ メッセージ編集済み 編集者: ぽんす 編集日時 2005-01-28 13:18 ] |