Skip to content

Commit b3657d7

Browse files
committed
Added AtomicBoolean class
1 parent bab5fa1 commit b3657d7

File tree

3 files changed

+317
-0
lines changed

3 files changed

+317
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
module Concurrent
2+
3+
# @!macro [attach] atomic_boolean
4+
#
5+
# A boolean value that can be updated atomically. Reads and writes to an atomic
6+
# boolean and thread-safe and guaranteed to succeed. Reads and writes may block
7+
# briefly but no explicit locking is required.
8+
#
9+
# @since 0.6.0
10+
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html java.util.concurrent.atomic.AtomicBoolean
11+
class MutexAtomicBoolean
12+
13+
# @!macro [attach] atomic_boolean_method_initialize
14+
#
15+
# Creates a new `AtomicBoolean` with the given initial value.
16+
#
17+
# @param [Boolean] init the initial value
18+
def initialize(initial = false)
19+
@value = !! initial
20+
@mutex = Mutex.new
21+
end
22+
23+
# @!macro [attach] atomic_boolean_method_value
24+
#
25+
# Retrieves the current `Boolean` value.
26+
#
27+
# @return [Boolean] the current value
28+
def value
29+
@mutex.synchronize{ @value }
30+
end
31+
32+
# @!macro [attach] atomic_boolean_method_value_eq
33+
#
34+
# Explicitly sets the value.
35+
#
36+
# @param [Boolean] value the new value to be set
37+
#
38+
# @return [Boolean] the current value
39+
def value=(value)
40+
@mutex.synchronize{ @value = !! value }
41+
end
42+
43+
# @!macro [attach] atomic_boolean_method_is_true
44+
#
45+
# Is the current value `true`?
46+
#
47+
# @return [Boolean] true if the current value is `true`, else false
48+
def true?
49+
@mutex.synchronize{ @value == true }
50+
end
51+
52+
# @!macro [attach] atomic_boolean_method_is_false
53+
#
54+
# Is the current value `true`?false
55+
#
56+
# @return [Boolean] true if the current value is `false`, else false
57+
def false?
58+
@mutex.synchronize{ @value != true }
59+
end
60+
61+
# @!macro [attach] atomic_boolean_method_make_true
62+
#
63+
# Explicitly sets the value to true.
64+
#
65+
# @return [Boolean] the current value
66+
def make_true
67+
@mutex.synchronize{ @value = true }
68+
nil
69+
end
70+
71+
# @!macro [attach] atomic_boolean_method_make_false
72+
#
73+
# Explicitly sets the value to false.
74+
#
75+
# @return [Boolean] the current value
76+
def make_false
77+
@mutex.synchronize{ @value = false }
78+
nil
79+
end
80+
end
81+
82+
if RUBY_PLATFORM == 'java'
83+
84+
# @!macro atomic_boolean
85+
class JavaAtomicBoolean
86+
87+
# @!macro atomic_boolean_method_initialize
88+
#
89+
def initialize(initial = false)
90+
@atomic = java.util.concurrent.atomic.AtomicBoolean.new(!! initial)
91+
end
92+
93+
# @!macro atomic_boolean_method_value
94+
#
95+
def value
96+
@atomic.get
97+
end
98+
99+
# @!macro atomic_boolean_method_value_eq
100+
#
101+
def value=(value)
102+
@atomic.set(!! value)
103+
end
104+
105+
# @!macro [attach] atomic_boolean_method_is_true
106+
def true?
107+
@atomic.get == true
108+
end
109+
110+
# @!macro [attach] atomic_boolean_method_is_false
111+
def false?
112+
@atomic.get != true
113+
end
114+
115+
# @!macro atomic_boolean_method_make_true
116+
def make_true
117+
@atomic.set(true)
118+
end
119+
120+
# @!macro atomic_boolean_method_make_false
121+
def make_false
122+
@atomic.set(false)
123+
end
124+
end
125+
126+
# @!macro atomic_boolean
127+
class AtomicBoolean < JavaAtomicBoolean
128+
end
129+
130+
else
131+
132+
# @!macro atomic_boolean
133+
class AtomicBoolean < MutexAtomicBoolean
134+
end
135+
end
136+
end

lib/concurrent/atomics.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require 'concurrent/atomic/atomic_boolean'
12
require 'concurrent/atomic/atomic_fixnum'
23
require 'concurrent/atomic/condition'
34
require 'concurrent/atomic/copy_on_notify_observer_set'
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
require 'spec_helper'
2+
3+
share_examples_for :atomic_boolean do
4+
5+
context 'construction' do
6+
7+
it 'sets the initial value' do
8+
described_class.new(true).value.should be_true
9+
end
10+
11+
it 'defaults the initial value to false' do
12+
described_class.new.value.should be_false
13+
end
14+
15+
it 'evaluates the truthiness of a true value' do
16+
described_class.new(10).value.should be_true
17+
end
18+
19+
it 'evaluates the truthiness of a false value' do
20+
described_class.new(nil).value.should be_false
21+
end
22+
end
23+
24+
context '#value' do
25+
26+
it 'returns the current value' do
27+
counter = described_class.new(true)
28+
counter.value.should be_true
29+
counter.make_false
30+
counter.value.should be_false
31+
counter.make_true
32+
counter.value.should be_true
33+
end
34+
end
35+
36+
context '#value=' do
37+
38+
it 'sets the #value to the given `Boolean`' do
39+
atomic = described_class.new(true)
40+
atomic.value = false
41+
atomic.value.should be_false
42+
end
43+
44+
it 'returns the new value' do
45+
atomic = described_class.new(false)
46+
(atomic.value = true).should be_true
47+
end
48+
49+
it 'evaluates the truthiness of a true value' do
50+
atomic = described_class.new(false)
51+
atomic.value = 10
52+
atomic.value.should be_true
53+
end
54+
55+
it 'evaluates the truthiness of a false value' do
56+
atomic = described_class.new(true)
57+
atomic.value = nil
58+
atomic.value.should be_false
59+
end
60+
end
61+
62+
context 'true?' do
63+
64+
specify { described_class.new(true).true?.should be_true }
65+
66+
specify { described_class.new(false).true?.should be_false }
67+
end
68+
69+
context 'false?' do
70+
71+
specify { described_class.new(true).false?.should be_false }
72+
73+
specify { described_class.new(false).false?.should be_true }
74+
end
75+
76+
context 'make_true' do
77+
78+
it 'makes a false value true and returns nil' do
79+
subject = described_class.new(false)
80+
subject.make_true.should be_nil
81+
subject.value.should be_true
82+
end
83+
84+
it 'keeps a true value true and returns nil' do
85+
subject = described_class.new(true)
86+
subject.make_true.should be_nil
87+
subject.value.should be_true
88+
end
89+
end
90+
91+
context 'make_false' do
92+
93+
it 'makes a true value false and returns nil' do
94+
subject = described_class.new(true)
95+
subject.make_false.should be_nil
96+
subject.value.should be_false
97+
end
98+
99+
it 'keeps a false value false and returns nil' do
100+
subject = described_class.new(false)
101+
subject.make_false.should be_nil
102+
subject.value.should be_false
103+
end
104+
end
105+
end
106+
107+
module Concurrent
108+
109+
describe MutexAtomicBoolean do
110+
111+
it_should_behave_like :atomic_boolean
112+
113+
specify 'construction is synchronized' do
114+
mutex = double('mutex')
115+
Mutex.should_receive(:new).once.with(no_args).and_return(mutex)
116+
described_class.new
117+
end
118+
119+
specify 'value is synchronized' do
120+
mutex = double('mutex')
121+
Mutex.stub(:new).with(no_args).and_return(mutex)
122+
mutex.should_receive(:synchronize)
123+
described_class.new.value
124+
end
125+
126+
specify 'value= is synchronized' do
127+
mutex = double('mutex')
128+
Mutex.stub(:new).with(no_args).and_return(mutex)
129+
mutex.should_receive(:synchronize)
130+
described_class.new.value = 10
131+
end
132+
133+
specify 'true? is synchronized' do
134+
mutex = double('mutex')
135+
Mutex.stub(:new).with(no_args).and_return(mutex)
136+
mutex.should_receive(:synchronize)
137+
described_class.new.true?
138+
end
139+
140+
specify 'false? is synchronized' do
141+
mutex = double('mutex')
142+
Mutex.stub(:new).with(no_args).and_return(mutex)
143+
mutex.should_receive(:synchronize)
144+
described_class.new.false?
145+
end
146+
147+
specify 'make_true is synchronized' do
148+
mutex = double('mutex')
149+
Mutex.stub(:new).with(no_args).and_return(mutex)
150+
mutex.should_receive(:synchronize)
151+
described_class.new.make_true
152+
end
153+
154+
specify 'make_false is synchronized' do
155+
mutex = double('mutex')
156+
Mutex.stub(:new).with(no_args).and_return(mutex)
157+
mutex.should_receive(:synchronize)
158+
described_class.new.make_false
159+
end
160+
end
161+
162+
if jruby?
163+
164+
describe JavaAtomicBoolean do
165+
it_should_behave_like :atomic_boolean
166+
end
167+
end
168+
169+
describe AtomicBoolean do
170+
if jruby?
171+
it 'inherits from JavaAtomicBoolean' do
172+
AtomicBoolean.ancestors.should include(JavaAtomicBoolean)
173+
end
174+
else
175+
it 'inherits from MutexAtomicBoolean' do
176+
AtomicBoolean.ancestors.should include(MutexAtomicBoolean)
177+
end
178+
end
179+
end
180+
end

0 commit comments

Comments
 (0)