Description
The wiki page about concurrency says that updating an object instance var is not guaranteed to be visibile to other threads, although this action is thread safe.
- I cannot understand how this is possible under Java Memory Model: if the update is thread safe, so we're using a lock or volatile variable some where, but those primitives ensure also visibility due to happens-before relation.
Am I missing something or the wiki page is wrong?
If I'm wrong and the wiki page is right, we've a bigger problem.
Look, for example, at this simple class
class Counter
def initialize
@mutex = Mutex.new
@value = 0
end
def increment
@mutex.synchronize { @value = @value + 1 }
end
def value
@mutex.synchronize { @value }
end
Now, @mutex
is set in constructor and is and instance variable, without visibility guarantees is possible that a thread sees it a nil
when calling increment
!
(Java solves this issue ensuring that any final field is visible after an object is constructed, non-final field must be synchronized and we can use the implicit lock to do so or a final one)
In other word, to safely develop multithread code in Ruby we need at minimum to be sure that fields set in constructor are visibile at least when they are used as "effectively final" fields.
- if JRuby already provides that guarantee I think it should be added to the wiki page, otherwise the core should be modified to achieve this result
(I've tried to look into sources and I think that JRuby already provide visibility between threads, but multihreading is very hard and it's better to be sure about those details :) )