Skip to content

Instantly share code, notes, and snippets.

@headius
Forked from rosenfeld/output.txt
Last active January 2, 2016 10:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save headius/8287681 to your computer and use it in GitHub Desktop.
Save headius/8287681 to your computer and use it in GitHub Desktop.
Example utility for doing synchronized updates of instance variables.
module Atomically
GLOBAL_MUTEX = Mutex.new
def atomically(varname, &block)
# check first to avoid locking if possible
instance_variable_get(varname) || ___atomically_update___(varname, &block)
end
def ___atomically_update___(varname)
# lock and do ||= update
___mutex___.synchronize do
instance_variable_get(varname) || instance_variable_set(varname, yield)
end
end
def ___mutex___
# check first to avoid locking if possible
@___mutex___ || ___mutex_init___
end
def ___mutex_init___
# global lock to instantiate mutex for this object...kinda heavy
GLOBAL_MUTEX.synchronize do
@___mutex___ ||= Mutex.new
end
end
end
class A
include Atomically
attr_reader :a
@@lock = Mutex.new
@@incrementer = 0
def a
sleep 1
atomically(:@a) { @@lock.synchronize{@@incrementer += 1} }
end
def incrementer
@@incrementer
end
end
a = A.new
100.times.map do
Thread.start{a.a}
end.each &:join
100.times.map do
Thread.start{A.new.a}
end.each &:join
p a.a, a.incrementer, A.new.a, a.incrementer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment