- PR -

Threadの一斉開始(完全同期)について

投稿者投稿内容
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2005-01-27 12:45
完全に同期したリクエストとは違うかもしれませんが、

Producer-Consumerのパターンを適用し、発行元がキューにリクエストをポストし、
Comsumerがリクエストを取り出し、すべてのスレッドに配信してやるというのはいかがでしょうか?

同一の発行時間で、同一のメッセージを投げることはとりあえず出来ます。
ToGo
常連さん
会議室デビュー日: 2002/03/16
投稿数: 46
投稿日時: 2005-01-27 18:09
引用:

(株)ぽちさんの書き込み (2005-01-25 17:20) より:

また、
内部では順次Threadが開始されるらしく、完全に同時刻でのログは取れません。


物理的にはCPUが1つしかなければスレッドの実行は逐次処理になります。スレッドの
切り替えはOSがスケジューリングしますが、極短い処理(数ミリ秒以内)であれば
スレッドの処理が完了してから次のスレッドにスケジューリングされると思われます。

取得する時刻については、System.currentTimeMillis()の場合、OSが利用している
クロック割り込みの分解能に左右されます。システムにより分解能は変わりますが、
x86 Windows2000では10msまたは15msの分解能のようです。SPARC Solarisだと10ms
または1msになります。
絶対時刻ではなく相対時刻でよい場合、J2SE 5.0(Tiger)のSystem.nanoTime()を
使うと分解能が良くなります。

引用:

同時に、複数Threadに対して通知したいのですが。
wait/notifyあたりを使用するのでしょうか。


論理的には、複数スレッドに処理開始を通知するなら、wait/notifyAll を使用する
ことになります。
J2SE 5.0(Tiger)では、java.util.concurrentパッケージのCountDownLatchクラスを
使うと少し簡単に実現できます。ちょっとオーバーヘッドがかかりますが、同じ
パッケージのExecutorServiceインタフェースのinvokeAllを使っても実現できます。
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2005-01-27 19:24
引用:

同時に、複数Threadに対して通知したいのですが。
wait/notifyあたりを使用するのでしょうか。



一つのウェイトセットに集めてnotifyAllを使えば通知は(ほぼ)同時に出来るとは思いますが、その後起こされたスレッド群がロックの取り合いを始めませんか?
まあ、すぐにsynchronized抜ければ誤差範囲だとは思いますが、一旦整列はしちゃいますよね。

むしろ、単純に共有オブジェクトの値を変化させてやるのがいいような気がします。

コード:
---foo.class---
public static boolean canGo = false;

---bar.class---
while(!foo.canGo){
 //まだ進んではいけないらしいので無限ループして待ってる。
 //同じCPUに割り当てられちゃった他の仲間のためにyeild();した方がいいかも
}
//ここに一斉にやりたい処理を書く



まあ、OSの都合やら何やらでCPUが物理的に複数積まれているからといって、Javaのマルチスレッドが本当にパラレルに動くかどうかとかにはまだ色々あるようですが……
http://www.idg.co.jp/lw/news/back/index20010824_01_solaris.html
ToGo
常連さん
会議室デビュー日: 2002/03/16
投稿数: 46
投稿日時: 2005-01-28 02:23
引用:

永井和彦さんの書き込み (2005-01-27 19:24) より:

むしろ、単純に共有オブジェクトの値を変化させてやるのがいいような気がします。


非volatileな変数をスレッド間で共有する場合、変数の値の変更が即座に他のスレッドで
読み出せることは保証されません。各スレッドが作業コピーを持つことが許されており、
作業コピー間で同じ変数でありながら異なる値を取ることがあります。volatile宣言を
するとスレッド間の整合性が保証されるはずですが、これはもしかするとJ2SE5.0(Tiger)
以降からの仕様かもしれません。(JSR-133の実装による)

引用:

まあ、OSの都合やら何やらでCPUが物理的に複数積まれているからといって、Javaのマルチスレッドが本当にパラレルに動くかどうかとかにはまだ色々あるようですが……
http://www.idg.co.jp/lw/news/back/index20010824_01_solaris.html


Solarisの場合、Solaris9からは1:1モデルがデフォルトとなっているようです。
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2005-01-28 11:17
引用:

非volatileな変数をスレッド間で共有する場合、変数の値の変更が即座に他のスレッドで
読み出せることは保証されません。各スレッドが作業コピーを持つことが許されており、
作業コピー間で同じ変数でありながら異なる値を取ることがあります。volatile宣言を
するとスレッド間の整合性が保証されるはずですが、これはもしかするとJ2SE5.0(Tiger)
以降からの仕様かもしれません。(JSR-133の実装による)



ご指摘有り難うございます。

恥ずかしながら、volatileに関しては、マルチスレッドプログラミングでlongやdoubleが面白い値を返さないようにするために付けるもの……くらいの認識しかありませんでした。

スレッド毎の作業コピー……先に挙げた結城さんの本でその辺に言及している記述があった気もしますが……すっかり頭から抜け落ちてしまっていました。
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2005-01-28 13:08
引用:

ToGoさんの書き込み (2005-01-28 02:23) より:
Solarisの場合、Solaris9からは1:1モデルがデフォルトとなっているようです。


最近は1:1が再注目されてる感じですね。
AIXではM:Nがデフォルトだったと思いますが、プログラマに対して
「1:1のほうがパフォーマンスが良くなることが多いですよ」という
アドバイスをしていたと思います。
NetBSDだとM:Nですが、こっちはM:Nだからどうこうというより、
SAはどうなんだ、という話になるでしょうか。

[ メッセージ編集済み 編集者: ぽんす 編集日時 2005-01-28 13:18 ]

スキルアップ/キャリアアップ(JOB@IT)