concurrent-ruby 0.9.2-java → 1.0.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +49 -1
- data/README.md +86 -120
- data/lib/concurrent.rb +14 -5
- data/lib/concurrent/agent.rb +587 -0
- data/lib/concurrent/array.rb +39 -0
- data/lib/concurrent/async.rb +296 -149
- data/lib/concurrent/atom.rb +135 -45
- data/lib/concurrent/atomic/abstract_thread_local_var.rb +38 -0
- data/lib/concurrent/atomic/atomic_boolean.rb +83 -118
- data/lib/concurrent/atomic/atomic_fixnum.rb +101 -163
- data/lib/concurrent/atomic/atomic_reference.rb +1 -8
- data/lib/concurrent/atomic/count_down_latch.rb +62 -103
- data/lib/concurrent/atomic/cyclic_barrier.rb +3 -1
- data/lib/concurrent/atomic/event.rb +1 -1
- data/lib/concurrent/atomic/java_count_down_latch.rb +39 -0
- data/lib/concurrent/atomic/java_thread_local_var.rb +50 -0
- data/lib/concurrent/atomic/mutex_atomic_boolean.rb +60 -0
- data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +91 -0
- data/lib/concurrent/atomic/mutex_count_down_latch.rb +43 -0
- data/lib/concurrent/atomic/mutex_semaphore.rb +115 -0
- data/lib/concurrent/atomic/read_write_lock.rb +5 -4
- data/lib/concurrent/atomic/reentrant_read_write_lock.rb +3 -1
- data/lib/concurrent/atomic/ruby_thread_local_var.rb +172 -0
- data/lib/concurrent/atomic/semaphore.rb +84 -178
- data/lib/concurrent/atomic/thread_local_var.rb +65 -294
- data/lib/concurrent/atomic_reference/jruby+truffle.rb +1 -0
- data/lib/concurrent/atomic_reference/jruby.rb +1 -1
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +14 -8
- data/lib/concurrent/atomic_reference/ruby.rb +1 -1
- data/lib/concurrent/atomics.rb +7 -37
- data/lib/concurrent/collection/copy_on_notify_observer_set.rb +7 -15
- data/lib/concurrent/collection/copy_on_write_observer_set.rb +7 -15
- data/lib/concurrent/collection/java_non_concurrent_priority_queue.rb +84 -0
- data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +927 -0
- data/lib/concurrent/collection/map/mri_map_backend.rb +66 -0
- data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +144 -0
- data/lib/concurrent/collection/map/synchronized_map_backend.rb +86 -0
- data/lib/concurrent/collection/non_concurrent_priority_queue.rb +143 -0
- data/lib/concurrent/collection/ruby_non_concurrent_priority_queue.rb +150 -0
- data/lib/concurrent/concern/dereferenceable.rb +9 -24
- data/lib/concurrent/concern/logging.rb +1 -1
- data/lib/concurrent/concern/obligation.rb +11 -20
- data/lib/concurrent/concern/observable.rb +38 -13
- data/lib/concurrent/configuration.rb +23 -152
- data/lib/concurrent/constants.rb +8 -0
- data/lib/concurrent/delay.rb +14 -12
- data/lib/concurrent/exchanger.rb +339 -41
- data/lib/concurrent/executor/abstract_executor_service.rb +134 -0
- data/lib/concurrent/executor/executor_service.rb +23 -359
- data/lib/concurrent/executor/immediate_executor.rb +3 -2
- data/lib/concurrent/executor/java_executor_service.rb +100 -0
- data/lib/concurrent/executor/java_single_thread_executor.rb +3 -3
- data/lib/concurrent/executor/java_thread_pool_executor.rb +3 -4
- data/lib/concurrent/executor/ruby_executor_service.rb +78 -0
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +10 -66
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +25 -22
- data/lib/concurrent/executor/safe_task_executor.rb +6 -7
- data/lib/concurrent/executor/serial_executor_service.rb +34 -0
- data/lib/concurrent/executor/serialized_execution.rb +10 -33
- data/lib/concurrent/executor/serialized_execution_delegator.rb +28 -0
- data/lib/concurrent/executor/simple_executor_service.rb +1 -10
- data/lib/concurrent/executor/single_thread_executor.rb +20 -10
- data/lib/concurrent/executor/timer_set.rb +8 -10
- data/lib/concurrent/executors.rb +12 -2
- data/lib/concurrent/future.rb +6 -4
- data/lib/concurrent/hash.rb +35 -0
- data/lib/concurrent/immutable_struct.rb +5 -1
- data/lib/concurrent/ivar.rb +12 -16
- data/lib/concurrent/lazy_register.rb +11 -8
- data/lib/concurrent/map.rb +180 -0
- data/lib/concurrent/maybe.rb +6 -3
- data/lib/concurrent/mutable_struct.rb +7 -6
- data/lib/concurrent/mvar.rb +26 -2
- data/lib/concurrent/{executor/executor.rb → options.rb} +5 -29
- data/lib/concurrent/promise.rb +7 -5
- data/lib/concurrent/scheduled_task.rb +13 -71
- data/lib/concurrent/settable_struct.rb +5 -4
- data/lib/concurrent/synchronization.rb +15 -3
- data/lib/concurrent/synchronization/abstract_lockable_object.rb +98 -0
- data/lib/concurrent/synchronization/abstract_object.rb +7 -146
- data/lib/concurrent/synchronization/abstract_struct.rb +2 -3
- data/lib/concurrent/synchronization/condition.rb +6 -4
- data/lib/concurrent/synchronization/jruby_lockable_object.rb +13 -0
- data/lib/concurrent/synchronization/jruby_object.rb +44 -0
- data/lib/concurrent/synchronization/lock.rb +3 -2
- data/lib/concurrent/synchronization/lockable_object.rb +72 -0
- data/lib/concurrent/synchronization/mri_lockable_object.rb +71 -0
- data/lib/concurrent/synchronization/mri_object.rb +43 -0
- data/lib/concurrent/synchronization/object.rb +140 -73
- data/lib/concurrent/synchronization/rbx_lockable_object.rb +65 -0
- data/lib/concurrent/synchronization/rbx_object.rb +30 -73
- data/lib/concurrent/synchronization/volatile.rb +34 -0
- data/lib/concurrent/thread_safe/synchronized_delegator.rb +50 -0
- data/lib/concurrent/thread_safe/util.rb +14 -0
- data/lib/concurrent/thread_safe/util/adder.rb +74 -0
- data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +30 -0
- data/lib/concurrent/thread_safe/util/cheap_lockable.rb +118 -0
- data/lib/concurrent/thread_safe/util/power_of_two_tuple.rb +38 -0
- data/lib/concurrent/thread_safe/util/striped64.rb +241 -0
- data/lib/concurrent/thread_safe/util/volatile.rb +75 -0
- data/lib/concurrent/thread_safe/util/xor_shift_random.rb +50 -0
- data/lib/concurrent/timer_task.rb +3 -4
- data/lib/concurrent/tuple.rb +86 -0
- data/lib/concurrent/tvar.rb +5 -1
- data/lib/concurrent/utility/at_exit.rb +1 -1
- data/lib/concurrent/utility/engine.rb +4 -0
- data/lib/concurrent/utility/monotonic_time.rb +3 -4
- data/lib/concurrent/utility/native_extension_loader.rb +50 -30
- data/lib/concurrent/version.rb +2 -2
- data/lib/concurrent_ruby_ext.jar +0 -0
- metadata +47 -12
- data/lib/concurrent/atomic/condition.rb +0 -78
- data/lib/concurrent/collection/priority_queue.rb +0 -360
- data/lib/concurrent/synchronization/java_object.rb +0 -34
- data/lib/concurrent/synchronization/monitor_object.rb +0 -27
- data/lib/concurrent/synchronization/mutex_object.rb +0 -43
- data/lib/concurrent/utilities.rb +0 -5
- data/lib/concurrent/utility/timeout.rb +0 -39
- data/lib/concurrent/utility/timer.rb +0 -26
- data/lib/concurrent_ruby.rb +0 -2
data/lib/concurrent/atom.rb
CHANGED
@@ -1,6 +1,41 @@
|
|
1
|
-
require 'concurrent/concern/dereferenceable'
|
2
1
|
require 'concurrent/atomic/atomic_reference'
|
3
|
-
require 'concurrent/
|
2
|
+
require 'concurrent/collection/copy_on_notify_observer_set'
|
3
|
+
require 'concurrent/concern/observable'
|
4
|
+
require 'concurrent/synchronization'
|
5
|
+
|
6
|
+
# @!macro [new] thread_safe_variable_comparison
|
7
|
+
#
|
8
|
+
# ## Thread-safe Variable Classes
|
9
|
+
#
|
10
|
+
# Each of the thread-safe variable classes is designed to solve a different
|
11
|
+
# problem. In general:
|
12
|
+
#
|
13
|
+
# * *{Concurrent::Agent}:* Shared, mutable variable providing independent,
|
14
|
+
# uncoordinated, *asynchronous* change of individual values. Best used when
|
15
|
+
# the value will undergo frequent, complex updates. Suitable when the result
|
16
|
+
# of an update does not need to be known immediately.
|
17
|
+
# * *{Concurrent::Atom}:* Shared, mutable variable providing independent,
|
18
|
+
# uncoordinated, *synchronous* change of individual values. Best used when
|
19
|
+
# the value will undergo frequent reads but only occasional, though complex,
|
20
|
+
# updates. Suitable when the result of an update must be known immediately.
|
21
|
+
# * *{Concurrent::AtomicReference}:* A simple object reference that can be
|
22
|
+
# atomically. Updates are synchronous but fast. Bast used when updates a
|
23
|
+
# simple set operations. Not suitable when updates are complex.
|
24
|
+
# {Concurrent::AtomicBoolean} and {Concurrent::AtomicFixnum} are similar
|
25
|
+
# but optimized for the given data type.
|
26
|
+
# * *{Concurrent::Exchanger}:* Shared, stateless synchronization point. Used
|
27
|
+
# when two or more threads need to exchange data. The threads will pair then
|
28
|
+
# block on each other until the exchange is complete.
|
29
|
+
# * *{Concurrent::MVar}:* Shared synchronization point. Used when one thread
|
30
|
+
# must give a value to another, which must take the value. The threads will
|
31
|
+
# block on each other until the exchange is complete.
|
32
|
+
# * *{Concurrent::ThreadLocalVar}:* Shared, mutable, isolated variable which
|
33
|
+
# holds a different value for each thread which has access. Often used as
|
34
|
+
# an instance variable in objects which must maintain different state
|
35
|
+
# for different threads.
|
36
|
+
# * *{Concurrent::TVar}:* Shared, mutable variables which provide
|
37
|
+
# *coordinated*, *synchronous*, change of *many* stated. Used when multiple
|
38
|
+
# value must change together, in an all-or-nothing transaction.
|
4
39
|
|
5
40
|
module Concurrent
|
6
41
|
|
@@ -18,11 +53,50 @@ module Concurrent
|
|
18
53
|
# new value to the result of running the given block if and only if that
|
19
54
|
# value validates.
|
20
55
|
#
|
21
|
-
#
|
56
|
+
# ## Example
|
57
|
+
#
|
58
|
+
# ```
|
59
|
+
# def next_fibonacci(set = nil)
|
60
|
+
# return [0, 1] if set.nil?
|
61
|
+
# set + [set[-2..-1].reduce{|sum,x| sum + x }]
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# # create an atom with aninitial value
|
65
|
+
# atom = Concurrent::Atom.new(next_fibonacci)
|
66
|
+
#
|
67
|
+
# # send a few update requests
|
68
|
+
# 5.times do
|
69
|
+
# atom.swap{|set| next_fibonacci(set) }
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# # get the current value
|
73
|
+
# atom.value #=> [0, 1, 1, 2, 3, 5, 8]
|
74
|
+
# ```
|
75
|
+
#
|
76
|
+
# ## Observation
|
77
|
+
#
|
78
|
+
# Atoms support observers through the {Concurrent::Observable} mixin module.
|
79
|
+
# Notification of observers occurs every time the value of the Atom changes.
|
80
|
+
# When notified the observer will receive three arguments: `time`, `old_value`,
|
81
|
+
# and `new_value`. The `time` argument is the time at which the value change
|
82
|
+
# occurred. The `old_value` is the value of the Atom when the change began
|
83
|
+
# The `new_value` is the value to which the Atom was set when the change
|
84
|
+
# completed. Note that `old_value` and `new_value` may be the same. This is
|
85
|
+
# not an error. It simply means that the change operation returned the same
|
86
|
+
# value.
|
87
|
+
#
|
88
|
+
# Unlike in Clojure, `Atom` cannot participate in {Concurrent::TVar} transactions.
|
89
|
+
#
|
90
|
+
# @!macro thread_safe_variable_comparison
|
22
91
|
#
|
23
92
|
# @see http://clojure.org/atoms Clojure Atoms
|
93
|
+
# @see http://clojure.org/state Values and Change - Clojure's approach to Identity and State
|
24
94
|
class Atom < Synchronization::Object
|
25
|
-
include Concern::
|
95
|
+
include Concern::Observable
|
96
|
+
|
97
|
+
safe_initialization!
|
98
|
+
private(*attr_atomic(:value))
|
99
|
+
public :value
|
26
100
|
|
27
101
|
# Create a new atom with the given initial value.
|
28
102
|
#
|
@@ -34,25 +108,20 @@ module Concurrent
|
|
34
108
|
# is acceptable else return false (preferrably) or raise an exception.
|
35
109
|
#
|
36
110
|
# @!macro deref_options
|
37
|
-
#
|
111
|
+
#
|
38
112
|
# @raise [ArgumentError] if the validator is not a `Proc` (when given)
|
39
113
|
def initialize(value, opts = {})
|
40
114
|
super()
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
@value = Concurrent::AtomicReference.new(value)
|
46
|
-
ns_set_deref_options(opts)
|
47
|
-
ensure_ivar_visibility!
|
115
|
+
@Validator = opts.fetch(:validator, -> v { true })
|
116
|
+
self.observers = Collection::CopyOnNotifyObserverSet.new
|
117
|
+
self.value = value
|
48
118
|
end
|
49
119
|
|
50
|
-
#
|
120
|
+
# @!method value
|
121
|
+
# The current value of the atom.
|
51
122
|
#
|
52
|
-
#
|
53
|
-
|
54
|
-
apply_deref_options(@value.value)
|
55
|
-
end
|
123
|
+
# @return [Object] The current value.
|
124
|
+
|
56
125
|
alias_method :deref, :value
|
57
126
|
|
58
127
|
# Atomically swaps the value of atom using the given block. The current
|
@@ -68,7 +137,7 @@ module Concurrent
|
|
68
137
|
# the application of the supplied block to a current value, atomically.
|
69
138
|
# However, because the block might be called multiple times, it must be free
|
70
139
|
# of side effects.
|
71
|
-
#
|
140
|
+
#
|
72
141
|
# @note The given block may be called multiple times, and thus should be free
|
73
142
|
# of side effects.
|
74
143
|
#
|
@@ -87,45 +156,66 @@ module Concurrent
|
|
87
156
|
def swap(*args)
|
88
157
|
raise ArgumentError.new('no block given') unless block_given?
|
89
158
|
|
90
|
-
|
91
|
-
|
92
|
-
|
159
|
+
loop do
|
160
|
+
old_value = value
|
161
|
+
begin
|
93
162
|
new_value = yield(old_value, *args)
|
94
|
-
|
95
|
-
|
163
|
+
break old_value unless valid?(new_value)
|
164
|
+
break new_value if compare_and_set(old_value, new_value)
|
165
|
+
rescue
|
166
|
+
break old_value
|
96
167
|
end
|
97
|
-
rescue
|
98
|
-
return @value.value
|
99
168
|
end
|
100
169
|
end
|
101
170
|
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
# at construction.
|
171
|
+
# Atomically sets the value of atom to the new value if and only if the
|
172
|
+
# current value of the atom is identical to the old value and the new
|
173
|
+
# value successfully validates against the (optional) validator given
|
174
|
+
# at construction.
|
107
175
|
#
|
108
|
-
#
|
109
|
-
#
|
176
|
+
# @param [Object] old_value The expected current value.
|
177
|
+
# @param [Object] new_value The intended new value.
|
110
178
|
#
|
111
|
-
#
|
179
|
+
# @return [Boolean] True if the value is changed else false.
|
112
180
|
def compare_and_set(old_value, new_value)
|
113
|
-
|
114
|
-
|
115
|
-
|
181
|
+
if valid?(new_value) && compare_and_set_value(old_value, new_value)
|
182
|
+
observers.notify_observers(Time.now, old_value, new_value)
|
183
|
+
true
|
184
|
+
else
|
185
|
+
false
|
186
|
+
end
|
116
187
|
end
|
117
188
|
|
118
|
-
|
119
|
-
|
120
|
-
#
|
121
|
-
#
|
122
|
-
#
|
123
|
-
|
124
|
-
|
125
|
-
|
189
|
+
# Atomically sets the value of atom to the new value without regard for the
|
190
|
+
# current value so long as the new value successfully validates against the
|
191
|
+
# (optional) validator given at construction.
|
192
|
+
#
|
193
|
+
# @param [Object] new_value The intended new value.
|
194
|
+
#
|
195
|
+
# @return [Object] The final value of the atom after all operations and
|
196
|
+
# validations are complete.
|
197
|
+
def reset(new_value)
|
198
|
+
old_value = value
|
199
|
+
if valid?(new_value)
|
200
|
+
self.value = new_value
|
201
|
+
observers.notify_observers(Time.now, old_value, new_value)
|
202
|
+
new_value
|
126
203
|
else
|
127
|
-
|
204
|
+
old_value
|
128
205
|
end
|
129
206
|
end
|
207
|
+
|
208
|
+
private
|
209
|
+
|
210
|
+
# Is the new value valid?
|
211
|
+
#
|
212
|
+
# @param [Object] new_value The intended new value.
|
213
|
+
# @return [Boolean] false if the validator function returns false or raises
|
214
|
+
# an exception else true
|
215
|
+
def valid?(new_value)
|
216
|
+
@Validator.call(new_value)
|
217
|
+
rescue
|
218
|
+
false
|
219
|
+
end
|
130
220
|
end
|
131
221
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'concurrent/constants'
|
2
|
+
|
3
|
+
module Concurrent
|
4
|
+
|
5
|
+
# @!macro thread_local_var
|
6
|
+
# @!macro internal_implementation_note
|
7
|
+
# @!visibility private
|
8
|
+
class AbstractThreadLocalVar
|
9
|
+
|
10
|
+
# @!macro thread_local_var_method_initialize
|
11
|
+
def initialize(default = nil)
|
12
|
+
@default = default
|
13
|
+
allocate_storage
|
14
|
+
end
|
15
|
+
|
16
|
+
# @!macro thread_local_var_method_get
|
17
|
+
def value
|
18
|
+
raise NotImplementedError
|
19
|
+
end
|
20
|
+
|
21
|
+
# @!macro thread_local_var_method_set
|
22
|
+
def value=(value)
|
23
|
+
raise NotImplementedError
|
24
|
+
end
|
25
|
+
|
26
|
+
# @!macro thread_local_var_method_bind
|
27
|
+
def bind(value, &block)
|
28
|
+
raise NotImplementedError
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
# @!visibility private
|
34
|
+
def allocate_storage
|
35
|
+
raise NotImplementedError
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,118 +1,85 @@
|
|
1
|
-
require 'concurrent/
|
1
|
+
require 'concurrent/atomic/mutex_atomic_boolean'
|
2
2
|
require 'concurrent/synchronization'
|
3
3
|
|
4
4
|
module Concurrent
|
5
5
|
|
6
|
-
|
6
|
+
###################################################################
|
7
|
+
|
8
|
+
# @!macro [new] atomic_boolean_method_initialize
|
7
9
|
#
|
8
|
-
#
|
9
|
-
# boolean and thread-safe and guaranteed to succeed. Reads and writes may block
|
10
|
-
# briefly but no explicit locking is required.
|
10
|
+
# Creates a new `AtomicBoolean` with the given initial value.
|
11
11
|
#
|
12
|
-
#
|
13
|
-
|
14
|
-
#
|
15
|
-
# Testing with Concurrent::CAtomicBoolean...
|
16
|
-
# 0.740000 0.000000 0.740000 ( 0.740206)
|
12
|
+
# @param [Boolean] initial the initial value
|
13
|
+
|
14
|
+
# @!macro [new] atomic_boolean_method_value_get
|
17
15
|
#
|
18
|
-
#
|
19
|
-
# Testing with Concurrent::MutexAtomicBoolean...
|
20
|
-
# 5.240000 2.520000 7.760000 ( 3.683000)
|
21
|
-
# Testing with Concurrent::JavaAtomicBoolean...
|
22
|
-
# 3.340000 0.010000 3.350000 ( 0.855000)
|
16
|
+
# Retrieves the current `Boolean` value.
|
23
17
|
#
|
24
|
-
# @
|
18
|
+
# @return [Boolean] the current value
|
19
|
+
|
20
|
+
# @!macro [new] atomic_boolean_method_value_set
|
25
21
|
#
|
26
|
-
#
|
22
|
+
# Explicitly sets the value.
|
27
23
|
#
|
28
|
-
#
|
29
|
-
|
30
|
-
|
31
|
-
# @!macro [attach] atomic_boolean_method_initialize
|
32
|
-
#
|
33
|
-
# Creates a new `AtomicBoolean` with the given initial value.
|
34
|
-
#
|
35
|
-
# @param [Boolean] initial the initial value
|
36
|
-
def initialize(initial = false)
|
37
|
-
super()
|
38
|
-
synchronize { ns_initialize(initial) }
|
39
|
-
end
|
40
|
-
|
41
|
-
# @!macro [attach] atomic_boolean_method_value_get
|
42
|
-
#
|
43
|
-
# Retrieves the current `Boolean` value.
|
44
|
-
#
|
45
|
-
# @return [Boolean] the current value
|
46
|
-
def value
|
47
|
-
synchronize { @value }
|
48
|
-
end
|
49
|
-
|
50
|
-
# @!macro [attach] atomic_boolean_method_value_set
|
51
|
-
#
|
52
|
-
# Explicitly sets the value.
|
53
|
-
#
|
54
|
-
# @param [Boolean] value the new value to be set
|
55
|
-
#
|
56
|
-
# @return [Boolean] the current value
|
57
|
-
def value=(value)
|
58
|
-
synchronize { @value = !!value }
|
59
|
-
end
|
24
|
+
# @param [Boolean] value the new value to be set
|
25
|
+
#
|
26
|
+
# @return [Boolean] the current value
|
60
27
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
def true?
|
67
|
-
synchronize { @value }
|
68
|
-
end
|
28
|
+
# @!macro [new] atomic_boolean_method_true_question
|
29
|
+
#
|
30
|
+
# Is the current value `true`
|
31
|
+
#
|
32
|
+
# @return [Boolean] true if the current value is `true`, else false
|
69
33
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
def false?
|
76
|
-
synchronize { !@value }
|
77
|
-
end
|
34
|
+
# @!macro [new] atomic_boolean_method_false_question
|
35
|
+
#
|
36
|
+
# Is the current value `false`
|
37
|
+
#
|
38
|
+
# @return [Boolean] true if the current value is `false`, else false
|
78
39
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
def make_true
|
85
|
-
synchronize { ns_make_value(true) }
|
86
|
-
end
|
40
|
+
# @!macro [new] atomic_boolean_method_make_true
|
41
|
+
#
|
42
|
+
# Explicitly sets the value to true.
|
43
|
+
#
|
44
|
+
# @return [Boolean] true is value has changed, otherwise false
|
87
45
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
def make_false
|
94
|
-
synchronize { ns_make_value(false) }
|
95
|
-
end
|
46
|
+
# @!macro [new] atomic_boolean_method_make_false
|
47
|
+
#
|
48
|
+
# Explicitly sets the value to false.
|
49
|
+
#
|
50
|
+
# @return [Boolean] true is value has changed, otherwise false
|
96
51
|
|
97
|
-
|
52
|
+
###################################################################
|
98
53
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
54
|
+
# @!macro [new] atomic_boolean_public_api
|
55
|
+
#
|
56
|
+
# @!method initialize(initial = false)
|
57
|
+
# @!macro atomic_boolean_method_initialize
|
58
|
+
#
|
59
|
+
# @!method value
|
60
|
+
# @!macro atomic_boolean_method_value_get
|
61
|
+
#
|
62
|
+
# @!method value=(value)
|
63
|
+
# @!macro atomic_boolean_method_value_set
|
64
|
+
#
|
65
|
+
# @!method true?
|
66
|
+
# @!macro atomic_boolean_method_true_question
|
67
|
+
#
|
68
|
+
# @!method false?
|
69
|
+
# @!macro atomic_boolean_method_false_question
|
70
|
+
#
|
71
|
+
# @!method make_true
|
72
|
+
# @!macro atomic_boolean_method_make_true
|
73
|
+
#
|
74
|
+
# @!method make_false
|
75
|
+
# @!macro atomic_boolean_method_make_false
|
103
76
|
|
104
|
-
|
105
|
-
def ns_make_value(value)
|
106
|
-
old = @value
|
107
|
-
@value = value
|
108
|
-
old != @value
|
109
|
-
end
|
110
|
-
end
|
77
|
+
###################################################################
|
111
78
|
|
112
79
|
# @!visibility private
|
113
80
|
# @!macro internal_implementation_note
|
114
81
|
AtomicBooleanImplementation = case
|
115
|
-
when
|
82
|
+
when defined?(JavaAtomicBoolean)
|
116
83
|
JavaAtomicBoolean
|
117
84
|
when defined?(CAtomicBoolean)
|
118
85
|
CAtomicBoolean
|
@@ -121,31 +88,29 @@ module Concurrent
|
|
121
88
|
end
|
122
89
|
private_constant :AtomicBooleanImplementation
|
123
90
|
|
124
|
-
# @!macro atomic_boolean
|
91
|
+
# @!macro [attach] atomic_boolean
|
92
|
+
#
|
93
|
+
# A boolean value that can be updated atomically. Reads and writes to an atomic
|
94
|
+
# boolean and thread-safe and guaranteed to succeed. Reads and writes may block
|
95
|
+
# briefly but no explicit locking is required.
|
96
|
+
#
|
97
|
+
# @!macro thread_safe_variable_comparison
|
98
|
+
#
|
99
|
+
# Testing with ruby 2.1.2
|
100
|
+
# Testing with Concurrent::MutexAtomicBoolean...
|
101
|
+
# 2.790000 0.000000 2.790000 ( 2.791454)
|
102
|
+
# Testing with Concurrent::CAtomicBoolean...
|
103
|
+
# 0.740000 0.000000 0.740000 ( 0.740206)
|
104
|
+
#
|
105
|
+
# Testing with jruby 1.9.3
|
106
|
+
# Testing with Concurrent::MutexAtomicBoolean...
|
107
|
+
# 5.240000 2.520000 7.760000 ( 3.683000)
|
108
|
+
# Testing with Concurrent::JavaAtomicBoolean...
|
109
|
+
# 3.340000 0.010000 3.350000 ( 0.855000)
|
110
|
+
#
|
111
|
+
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html java.util.concurrent.atomic.AtomicBoolean
|
125
112
|
#
|
126
|
-
#
|
113
|
+
# @!macro atomic_boolean_public_api
|
127
114
|
class AtomicBoolean < AtomicBooleanImplementation
|
128
|
-
|
129
|
-
# @!method initialize(initial = false)
|
130
|
-
# @!macro atomic_boolean_method_initialize
|
131
|
-
|
132
|
-
# @!method value
|
133
|
-
# @!macro atomic_boolean_method_value_get
|
134
|
-
|
135
|
-
# @!method value=(value)
|
136
|
-
# @!macro atomic_boolean_method_value_set
|
137
|
-
|
138
|
-
# @!method true?
|
139
|
-
# @!macro atomic_boolean_method_true_question
|
140
|
-
|
141
|
-
# @!method false?
|
142
|
-
# @!macro atomic_boolean_method_false_question
|
143
|
-
|
144
|
-
# @!method make_true
|
145
|
-
# @!macro atomic_boolean_method_make_true
|
146
|
-
|
147
|
-
# @!method make_false
|
148
|
-
# @!macro atomic_boolean_method_make_false
|
149
|
-
|
150
115
|
end
|
151
116
|
end
|