超おおざっぱなスレッドセーフクラス

日記放置すぎワロタ
全てのメソッドを、同時実行不可にしちゃう

threadsafe.rb

require "thread"

module ThreadSafe
  def self.new(klass)
    ret = Class.new
    ret.instance_eval {
      define_method :initialize do
        @mutex = Mutex.new
        @base  = klass.new
      end
      define_method :method_missing do |method, *arguments|
        self.class.instance_eval {
          define_method(method) { |*args|
            @mutex.synchronize { @base.send method, *args }
          }
        }
        @mutex.synchronize { @base.send method, *arguments }
      end
    }
    ret
  end
end

こうやって使う

ThreadSafeFooBar = ThreadSafe.new(FooBar)

サンプル

require "threadsafe"

class A
  def initialize; @x = 0; end
  def plus
    x = @x
    sleep 0.01
    @x = x + 1
  end
  attr_reader :x
end
B = ThreadSafe.new(A)

# 下記の『結果( a = A.new の場合、環境によって異なるはず )』はこっちを有効に
a = A.new

# 下記の『結果( a = B.new の場合 )』はこっちを有効に
#a = B.new


threads = []
10.times {
  threads << Thread.fork { 10.times { a.plus } }
}
threads.each { |t| t.join }
puts a.x

結果( a = A.new の場合、環境によって異なるはず )

ruby test.rb
10

結果( a = B.new の場合 )

ruby test.rb
100