Module: Concurrent::Synchronization — Concurrent

Class List Method List File List

# Module: Concurrent::Synchronization

Defined in:
  lib/concurrent/synchronization.rb,
  lib/concurrent/synchronization/lock.rb,
  lib/concurrent/synchronization/object.rb,
  lib/concurrent/synchronization/volatile.rb,
  lib/concurrent/synchronization/condition.rb,
  lib/concurrent/synchronization/mri_object.rb,
  lib/concurrent/synchronization/rbx_object.rb,
  lib/concurrent/synchronization/jruby_object.rb,
  lib/concurrent/synchronization/truffle_object.rb,
  lib/concurrent/synchronization/lockable_object.rb,
  lib/concurrent/synchronization/abstract_struct.rb,
  lib/concurrent/synchronization/abstract_object.rb,
  lib/concurrent/synchronization/rbx_lockable_object.rb,
  lib/concurrent/synchronization/mri_lockable_object.rb,
  lib/concurrent/synchronization/jruby_lockable_object.rb,
  lib/concurrent/synchronization/truffle_lockable_object.rb,
  lib/concurrent/synchronization/abstract_lockable_object.rb

## Overview

# Synchronization

This document is moved to Google documents. It will be moved here once final and stabilized.

# Concurrent Ruby Notes

## Locks

Concurrent Ruby also has an internal extension of `Object` called `LockableObject`, which provides same synchronization primitives as Java's Object: `synchronize(&block)`, `wait(timeout = nil)`, `wait_until(timeout = nil, &condition)`, `signal`, `broadcast`. This class is intended for internal use in `concurrent-ruby` only and it does not support subclassing (since it cannot protect its lock from its children, for more details see this article). It has minimal interface to be able to use directly locking available on given platforms.

For non-internal use there is `Lock` and `Condition` implementation in `Synchronization` namespace, a condition can be obtained with `new_condition` method on `Lock`. So far their implementation is naive and requires more work. API is not expected to change.

## Method names conventions

Methods starting with `ns_` are marking methods that are not using synchronization by themselves, they have to be used inside synchronize block. They are usually used in pairs to separate the synchronization from behavior and to allow to call methods in the same object without double locking.

    class Node
      # ...
      def left
        synchronize { ns_left }
      end

      def right
        synchronize { ns_right }
      end

      def to_a
        # avoids double locking
        synchronize { [ns_left, ns_right] }
      end

      private

      def ns_left
        @left
      end

      def ns_right
        @right
      end
      # ...
    end

## Piggybacking

Any write executed before volatile write based on program-order is visible to the volatile read as well, which allows piggybacking. Because it creates synchronizes-with (JMM term) order between volatile write and read, which participates in creating happens-before order.

This trick is used in some of the abstractions, to avoid unnecessary synchronization or volatile declarations.

## Defined Under Namespace

Modules: JRubyAttrVolatile, MriAttrVolatile, RbxAttrVolatile, TruffleAttrVolatile Classes: Condition, Lock, Object, TruffleLockableObject

## Constant Summary

Volatile =

Volatile adds the attr_volatile class method when included.

foo = Foo.new foo.bar => 1 foo.bar = 2 => 2

Examples:

    class Foo
      include Concurrent::Synchronization::Volatile

      attr_volatile :bar

      def initialize
        self.bar = 1
      end
    end

      case
      when Concurrent.on_cruby?
        MriAttrVolatile
      when Concurrent.on_jruby?
        JRubyAttrVolatile
      when Concurrent.on_rbx? || Concurrent.on_truffle?
        RbxAttrVolatile
      else
        MriAttrVolatile
      end