A purely functional synchronization primitive which represents a single value which may not yet be available.
A mutable location, that is either empty or contains
a value of type A
.
A mutable location, that is either empty or contains
a value of type A
.
It has the following fundamental atomic operations:
put
The MVar
is appropriate for building synchronization
primitives and performing simple inter-thread communications.
If it helps, it's similar with a BlockingQueue(capacity = 1)
,
except that it doesn't block any threads, all waiting being
done asynchronously (via Async or Concurrent data types,
such as IO).
Given its asynchronous, non-blocking nature, it can be used on top of Javascript as well.
Inspired by Control.Concurrent.MVar
from Haskell and
by scalaz.concurrent.MVar
.
An asynchronous, concurrent mutable reference.
An asynchronous, concurrent mutable reference.
Provides safe concurrent access and modification of its content, but no
functionality for synchronisation, which is instead handled by Deferred.
For this reason, a Ref
is always initialised to a value.
The default implementation is nonblocking and lightweight, consisting essentially
of a purely functional wrapper over an AtomicReference
.
A purely functional semaphore.
A purely functional semaphore.
A semaphore has a non-negative number of permits available. Acquiring a permit decrements the current number of permits and releasing a permit increases the current number of permits. An acquire that occurs when there are no permits available results in semantic blocking until a permit becomes available.
Blocking acquires are cancelable if the semaphore is created with Semaphore.apply
(and hence, with a Concurrent[F]
instance). Blocking acquires are non-cancelable
if the semaphore is created with Semaphore.async
(and hence, with an Async[F]
instance).
A purely functional synchronization primitive which represents a single value which may not yet be available.
When created, a
Deferred
is empty. It can then be completed exactly once, and never be made empty again.get
on an emptyDeferred
will block until theDeferred
is completed.get
on a completedDeferred
will always immediately return its content.complete(a)
on an emptyDeferred
will set it toa
, and notify any and all readers currently blocked on a call toget
.complete(a)
on aDeferred
that has already been completed will not modify its content, and result in a failedF
.Albeit simple,
Deferred
can be used in conjunction with Ref to build complex concurrent behaviour and data structures like queues and semaphores.Finally, the blocking mentioned above is semantic only, no actual threads are blocked by the implementation.