#!/usr/bin/ruby require 'monitor' class ObjectWrapper def initialize(wrapped_object) @__wrapped_object = wrapped_object end :private def method_missing(id, *args, &block) __wrap(id, *args, &block) end def __wrap_real(id, *args, &block) if block.nil? return @__wrapped_object.__send__(id, *args) else return @__wrapped_object.__send__(id, *args) { |*args2| block.call(*args2) } end end :public def __wrap(id, *args, &block) __wrap_real(id, *args, &block) end end class Synchronizator < ObjectWrapper def initialize(wrapped_object) super @__wrapped_object.extend(MonitorMixin) end def __wrap(id, *args, &block) @__wrapped_object.synchronize { __wrap_real(id, *args, &block) } end end Thread.abort_on_exception = true def thr(list, number) list.each { |i| puts "#{number}: #{i}" sleep 0.02 } end list = [ 0, 1, 2, 3 ] puts "without synchronizator:" for i in 1..3 Thread.new { thr(list, i) } end sleep 1 puts "\nwith synchronizator:" l_ = Synchronizator.new(list) for i in 1..3 Thread.new { thr(l_, i) } end sleep 1