それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Rubyでマルチスレッド その6 # Balking

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