class Concurrent::AbstractExchanger
@!macro [attach] exchanger
A synchronization point at which threads can pair and swap elements within pairs. Each thread presents some object on entry to the exchange method, matches with a partner thread, and receives its partner's object on return. @!macro thread_safe_variable_comparison This implementation is very simple, using only a single slot for each exchanger (unlike more advanced implementations which use an "arena"). This approach will work perfectly fine when there are only a few threads accessing a single `Exchanger`. Beyond a handful of threads the performance will degrade rapidly due to contention on the single slot, but the algorithm will remain correct. @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html java.util.concurrent.Exchanger @!macro edge_warning @example exchanger = Concurrent::Exchanger.new threads = [ Thread.new { puts "first: " << exchanger.exchange('foo', 1) }, #=> "first: bar" Thread.new { puts "second: " << exchanger.exchange('bar', 1) } #=> "second: foo" ] threads.each {|t| t.join(2) }
@!visibility private
Constants
- CANCEL
@!visibility private
Public Class Methods
new()
click to toggle source
@!macro [attach] exchanger_method_initialize
Calls superclass method
# File lib/concurrent/exchanger.rb, line 48 def initialize super end
Public Instance Methods
exchange(value, timeout = nil)
click to toggle source
@!macro [attach] exchanger_method_do_exchange
Waits for another thread to arrive at this exchange point (unless the current thread is interrupted), and then transfers the given object to it, receiving its object in return. The timeout value indicates the approximate number of seconds the method should block while waiting for the exchange. When the timeout value is `nil` the method will block indefinitely. @param [Object] value the value to exchange with another thread @param [Numeric, nil] timeout in seconds, `nil` blocks indefinitely
@!macro [attach] exchanger_method_exchange
In some edge cases when a `timeout` is given a return value of `nil` may be ambiguous. Specifically, if `nil` is a valid value in the exchange it will be impossible to tell whether `nil` is the actual return value or if it signifies timeout. When `nil` is a valid value in the exchange consider using {#exchange!} or {#try_exchange} instead. @return [Object] the value exchanged by the other thread or `nil` on timeout
# File lib/concurrent/exchanger.rb, line 73 def exchange(value, timeout = nil) (value = do_exchange(value, timeout)) == CANCEL ? nil : value end
exchange!(value, timeout = nil)
click to toggle source
@!macro exchanger_method_do_exchange
@!macro [attach] exchanger_method_exchange_bang
On timeout a {Concurrent::TimeoutError} exception will be raised. @return [Object] the value exchanged by the other thread @raise [Concurrent::TimeoutError] on timeout
# File lib/concurrent/exchanger.rb, line 85 def exchange!(value, timeout = nil) if (value = do_exchange(value, timeout)) == CANCEL raise Concurrent::TimeoutError else value end end
try_exchange(value, timeout = nil)
click to toggle source
@!macro exchanger_method_do_exchange
@!macro [attach] exchanger_method_try_exchange
The return value will be a {Concurrent::Maybe} set to `Just` on success or `Nothing` on timeout. @return [Concurrent::Maybe] on success a `Just` maybe will be returned with the item exchanged by the other thread as `#value`; on timeout a `Nothing` maybe will be returned with {Concurrent::TimeoutError} as `#reason` @example exchanger = Concurrent::Exchanger.new result = exchanger.exchange(:foo, 0.5) if result.just? puts result.value #=> :bar else puts 'timeout' end
# File lib/concurrent/exchanger.rb, line 115 def try_exchange(value, timeout = nil) if (value = do_exchange(value, timeout)) == CANCEL Concurrent::Maybe.nothing(Concurrent::TimeoutError) else Concurrent::Maybe.just(value) end end
Private Instance Methods
do_exchange(value, timeout)
click to toggle source
@!macro exchanger_method_do_exchange
@return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout
# File lib/concurrent/exchanger.rb, line 128 def do_exchange(value, timeout) raise NotImplementedError end