Class: Concurrent::Synchronization::Object
- Inherits:
-
ObjectImplementation
- Object
- Concurrent::Synchronization::Object
- Defined in:
- lib/concurrent/synchronization/object.rb
Overview
Abstract object providing final, volatile, ans CAS extensions to build other concurrent abstractions.
-
final instance variables see Object.safe_initialization!
-
volatile instance variables see Object.attr_volatile
-
volatile instance variables see Object.attr_atomic
Direct Known Subclasses
Atom, LazyRegister, MVar, Maybe, ReadWriteLock, ReentrantReadWriteLock, TVar
Class Method Summary collapse
-
.attr_atomic(*names) ⇒ Array<Symbol>
Creates methods for reading and writing to a instance variable with volatile (Java) semantic as Object.attr_volatile does.
-
.attr_volatile(*names) ⇒ Array<Symbol>
Creates methods for reading and writing (as ‘attr_accessor` does) to a instance variable with volatile (Java) semantic.
-
.ensure_safe_initialization_when_final_fields_are_present ⇒ Object
For testing purposes, quite slow.
- .new(*args, &block) ⇒ Object
-
.safe_initialization! ⇒ Object
By calling this method on a class, it and all its children are marked to be constructed safely.
-
.safe_initialization? ⇒ true, false
If this class is safely initialized.
-
.volatile_cas_fields(inherited = true) ⇒ Array<Symbol>
Returns defined volatile with CAS fields on this class.
Instance Method Summary collapse
-
#initialize ⇒ Object
constructor
Has to be called by children.
Constructor Details
#initialize ⇒ Object
Has to be called by children.
34 35 36 37 |
# File 'lib/concurrent/synchronization/object.rb', line 34 def initialize super initialize_volatile_with_cas end |
Class Method Details
.attr_atomic(*names) ⇒ Array<Symbol>
Creates methods for reading and writing to a instance variable with volatile (Java) semantic as attr_volatile does. The instance variable should be accessed oly through generated methods. This method generates following methods: ‘value`, `value=(new_value) #=> new_value`, `swap_value(new_value) #=> old_value`, `compare_and_set_value(expected, value) #=> true || false`, `update_value(&block)`.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/concurrent/synchronization/object.rb', line 92 def self.attr_atomic(*names) @volatile_cas_fields ||= [] @volatile_cas_fields += names safe_initialization! define_initialize_volatile_with_cas names.each do |name| ivar = :"@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }}" class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{name} #{ivar}.get end def #{name}=(value) #{ivar}.set value end def swap_#{name}(value) #{ivar}.swap value end def compare_and_set_#{name}(expected, value) #{ivar}.compare_and_set expected, value end def update_#{name}(&block) #{ivar}.update(&block) end RUBY end names.flat_map { |n| [n, :"#{n}=", :"swap_#{n}", :"compare_and_set_#{n}", :"update_#{n}"] } end |
.attr_volatile(*names) ⇒ Array<Symbol>
Creates methods for reading and writing (as ‘attr_accessor` does) to a instance variable with volatile (Java) semantic. The instance variable should be accessed oly through generated methods.
|
# File 'lib/concurrent/synchronization/object.rb', line 26
|
.ensure_safe_initialization_when_final_fields_are_present ⇒ Object
For testing purposes, quite slow. Injects assert code to new method which will raise if class instance contains any instance variables with CamelCase names and isn’t safe_initialization?.
71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/concurrent/synchronization/object.rb', line 71 def self.ensure_safe_initialization_when_final_fields_are_present Object.class_eval do def self.new(*) object = super ensure has_final_field = object.instance_variables.any? { |v| v.to_s =~ /^@[A-Z]/ } if has_final_field && !safe_initialization? raise "there was an instance of #{object.class} with final field but not marked with safe_initialization!" end end end end |
.new(*args, &block) ⇒ Object
54 55 56 57 58 |
# File 'lib/concurrent/synchronization/object.rb', line 54 def self.new(*args, &block) object = super(*args, &block) ensure object. if object end |
.safe_initialization! ⇒ Object
By calling this method on a class, it and all its children are marked to be constructed safely. Meaning that all writes (ivar initializations) are made visible to all readers of newly constructed object. It ensures same behaviour as Java’s final fields.
50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/concurrent/synchronization/object.rb', line 50 def self.safe_initialization! # define only once, and not again in children return if safe_initialization? def self.new(*args, &block) object = super(*args, &block) ensure object. if object end @safe_initialization = true end |
.safe_initialization? ⇒ true, false
Returns if this class is safely initialized.
64 65 66 67 |
# File 'lib/concurrent/synchronization/object.rb', line 64 def self.safe_initialization? @safe_initialization = false unless defined? @safe_initialization @safe_initialization || (superclass.respond_to?(:safe_initialization?) && superclass.safe_initialization?) end |
.volatile_cas_fields(inherited = true) ⇒ Array<Symbol>
Returns defined volatile with CAS fields on this class.
127 128 129 130 131 |
# File 'lib/concurrent/synchronization/object.rb', line 127 def self.volatile_cas_fields(inherited = true) @volatile_cas_fields ||= [] ((superclass.volatile_cas_fields if superclass.respond_to?(:volatile_cas_fields) && inherited) || []) + @volatile_cas_fields end |