Rubyで結城浩せんせいのJavaマルチスレッド本をやってみる試み、その5
Balking
Balkinは待たずに、他の仕事を片付けます。一方でGuarded SuspensionはWaitセットで待つ。Balking は先に進みます。
Guarded Suspensionのこんなところが嫌なので、Balkingパターンを使う。
- Waitセットが面倒だよね。
- 定期的にチェックしたらいいじゃん。
- 待っている間に他の仕事やっとくね。
ってことです
#!/usr/bin/env ruby # Balking の例 require 'thread' class SaverThread < Thread attr_reader :name def initialize name , data @name = name @data = data block = Proc.new{ while true do data.save() sleep rand(5) end } super(&block) end end class ChangerThread < Thread attr_reader :name def initialize name, data @name = name @data = data block = Proc.new{ i = 0; while true do i = i+1 data.change( "No. #{i}" ) sleep rand(5) data.save end } super(&block) end end class DataClass def initialize filename, content @filename= filename @content = content @changed = true @m = Mutex.new end def change content @m.synchronize{ @content = content @changed = true } end def save @m.synchronize{ return if @changed == false self.doSave @changed = false } end def doSave puts Thread.current.name + " calls doSave content = #{@content}" open(@filename , "w") do |f| f.write @content end end end d = DataClass.new("sample06.txt", "started") threads = [ SaverThread.new( "SaverThread", d ), ChangerThread.new("ChangerThread" ,d) ] threads.each{|t|t.join} puts "END"
Guarded SuspensionとBalking
@m.synchronize { return if self.changed? == false
@m.synchronize { while( self.changed? == false ) do @cv.wait(@m)
Waitをしないぶん、速く応答できます。Returnするとき、「準備中です」とか応答しておけばいい。そうえいばXmlHttp.Requestがこんな感じだよね。
待ちたいのが処理結果なら。
処理の呼び出し(Invoke/Execution)が必要で待っている間に他のことをしたいならBalking。
結果だけ欲しいならFutureでチケット貰って後でとり行けばいいのです。
- 病院の診察待ちをします(Guarded Suspension)。
- 処方箋を貰います(Future)。
- 薬局が混んでたら、待たずに買い物をして1時間後にまた来ます。(Balking)
- クスリを貰います(RealData)
で
- 病院全体:ActiveObject