Class AtomicCounter
- java.lang.Object
-
- org.agrona.concurrent.status.AtomicCounter
-
- All Implemented Interfaces:
java.lang.AutoCloseable
public class AtomicCounter extends java.lang.Object implements java.lang.AutoCloseable
Atomic counter that is backed by anAtomicBuffer
that can be read across threads and processes.In most cases you want to pair the appropriate methods for ordering. E.g.
- an
increment()
(which has volatile semantics) should be combined with aget()
. - an
incrementRelease()
with agetAcquire()
. - an
incrementOpaque()
with agetOpaque()
. - an
incrementPlain()
with agetPlain()
.
-
-
Field Summary
Fields Modifier and Type Field Description private long
addressOffset
private byte[]
byteArray
private java.nio.ByteBuffer
byteBuffer
private CountersManager
countersManager
private int
id
private boolean
isClosed
-
Constructor Summary
Constructors Constructor Description AtomicCounter(AtomicBuffer buffer, int counterId)
Map a counter over a buffer.AtomicCounter(AtomicBuffer buffer, int counterId, CountersManager countersManager)
Map a counter over a buffer.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description AtomicCounter
appendToLabel(java.lang.String suffix)
Append to the label for a counter constructed with aCountersManager
.void
close()
Close counter and free the counter slot for reuse of connected toCountersManager
.boolean
compareAndSet(long expectedValue, long updateValue)
Compare the current value to expected and if true then set to the update value atomically.long
decrement()
Perform an atomic decrement that will not lose updates across threads.long
decrementOpaque()
Perform a non-atomic decrement using opaque semantics.long
decrementOrdered()
Perform an atomic decrement that is not safe across threads.long
decrementPlain()
Decrements the counter.long
decrementRelease()
Decrements the counter non-atomically with release semantics.void
disconnectCountersManager()
Disconnect fromCountersManager
if allocated, so it can be closed without freeing the slot.long
get()
Get the value for the counter with volatile semantics.long
getAcquire()
Get the value for the counter with acquire semantics.long
getAndAdd(long increment)
Add an increment to the counter that will not lose updates across threads.long
getAndAddOpaque(long increment)
Adds an increment to the counter non-atomically.long
getAndAddOrdered(long increment)
Add an increment to the counter with ordered store semantics.long
getAndAddPlain(long increment)
Adds an increment to the counter non-atomically.long
getAndAddRelease(long increment)
Adds an increment to the counter non-atomically.long
getAndSet(long value)
Get the current value of a counter and atomically set it to a new value.long
getOpaque()
Get the value for the counter with opaque semantics.long
getPlain()
Get the value of the counter using plain memory semantics.long
getWeak()
Get the value of the counter using weak ordering semantics.int
id()
Identity for the counter within theCountersManager
.long
increment()
Perform an atomic increment that will not lose updates across threads.long
incrementOpaque()
Perform a non-atomic increment using opaque semantics.long
incrementOrdered()
Perform an atomic increment that is not safe across threads.long
incrementPlain()
Increment the counter.long
incrementRelease()
Perform a non-atomic increment with release semantics.boolean
isClosed()
Has this counter been closed?java.lang.String
label()
Return the label for the counter within theCountersManager
.boolean
proposeMax(long proposedValue)
Set the value to a new proposedValue if greater than the current value with plain memory semantics.boolean
proposeMaxOpaque(long proposedValue)
Set the value to a new proposedValue if greater than the current value.boolean
proposeMaxOrdered(long proposedValue)
Set the value to a new proposedValue if greater than the current value with memory ordering semantics.boolean
proposeMaxRelease(long proposedValue)
Set the value to a new proposedValue if greater than the current value.void
set(long value)
Set the counter with volatile semantics.void
setOpaque(long value)
Set the counter value atomically.void
setOrdered(long value)
Set the counter with ordered semantics.void
setPlain(long value)
Set the counter value with plain memory semantics.void
setRelease(long value)
Set the counter value atomically.void
setWeak(long value)
Set the counter with normal semantics.java.lang.String
toString()
void
updateKey(java.util.function.Consumer<MutableDirectBuffer> keyFunc)
Update the key for a counter constructed with aCountersManager
.void
updateKey(DirectBuffer keyBuffer, int offset, int length)
Update the key for a counter constructed with aCountersManager
.void
updateLabel(java.lang.String newLabel)
Update the label for the counter constructed with aCountersManager
.
-
-
-
Field Detail
-
isClosed
private boolean isClosed
-
id
private final int id
-
addressOffset
private final long addressOffset
-
byteArray
private final byte[] byteArray
-
countersManager
private CountersManager countersManager
-
byteBuffer
private final java.nio.ByteBuffer byteBuffer
-
-
Constructor Detail
-
AtomicCounter
public AtomicCounter(AtomicBuffer buffer, int counterId)
Map a counter over a buffer. This version will NOT free the counter on close.- Parameters:
buffer
- containing the counter.counterId
- identifier of the counter.
-
AtomicCounter
public AtomicCounter(AtomicBuffer buffer, int counterId, CountersManager countersManager)
Map a counter over a buffer. This version will free the counter on close.- Parameters:
buffer
- containing the counter.counterId
- identifier for the counter.countersManager
- to be called to free the counter on close.
-
-
Method Detail
-
id
public int id()
Identity for the counter within theCountersManager
.- Returns:
- identity for the counter within the
CountersManager
.
-
disconnectCountersManager
public void disconnectCountersManager()
Disconnect fromCountersManager
if allocated, so it can be closed without freeing the slot.
-
close
public void close()
Close counter and free the counter slot for reuse of connected toCountersManager
.- Specified by:
close
in interfacejava.lang.AutoCloseable
-
isClosed
public boolean isClosed()
Has this counter been closed?- Returns:
- true if this counter has already been closed.
-
label
public java.lang.String label()
Return the label for the counter within theCountersManager
.- Returns:
- the label for the counter within the
CountersManager
.
-
updateLabel
public void updateLabel(java.lang.String newLabel)
Update the label for the counter constructed with aCountersManager
.- Parameters:
newLabel
- for the counter with aCountersManager
.- Throws:
java.lang.IllegalStateException
- is not constructedCountersManager
.
-
appendToLabel
public AtomicCounter appendToLabel(java.lang.String suffix)
Append to the label for a counter constructed with aCountersManager
.- Parameters:
suffix
- for the counter within aCountersManager
.- Returns:
- this for a fluent API.
- Throws:
java.lang.IllegalStateException
- is not constructedCountersManager
.
-
updateKey
public void updateKey(java.util.function.Consumer<MutableDirectBuffer> keyFunc)
Update the key for a counter constructed with aCountersManager
.- Parameters:
keyFunc
- callback to use to update the counter's key- Throws:
java.lang.IllegalStateException
- is not constructedCountersManager
.
-
updateKey
public void updateKey(DirectBuffer keyBuffer, int offset, int length)
Update the key for a counter constructed with aCountersManager
.- Parameters:
keyBuffer
- contains key data to be copied into the counter.offset
- start of the key data within the keyBufferlength
- length of the data within the keyBuffer (must be <=CountersReader.MAX_KEY_LENGTH
)- Throws:
java.lang.IllegalStateException
- is not constructedCountersManager
.
-
increment
public long increment()
Perform an atomic increment that will not lose updates across threads.- Returns:
- the previous value of the counter
-
incrementOrdered
public long incrementOrdered()
Perform an atomic increment that is not safe across threads.This method is identical to
incrementRelease()
and that method should be used instead.- Returns:
- the previous value of the counter
-
incrementRelease
public long incrementRelease()
Perform a non-atomic increment with release semantics.It can result into lost updates due to race condition when called concurrently.
The load has plain memory semantics and the store has release memory semantics.
The typical use-case is when there is a single writer thread and one or more reader threads and causality needs to be preserved using the
getAcquire()
.This method is likely to outperform the
increment()
. So if there is just a single mutator thread, and one or more reader threads, then it is likely you will prefer this method.If no memory ordering is needed, have a look at the
incrementOpaque()
.- Returns:
- the previous value of the counter
- Since:
- 2.1.0
-
incrementOpaque
public long incrementOpaque()
Perform a non-atomic increment using opaque semantics.It can result into lost updates due to race condition when called concurrently.
The load has plain memory semantics and the store has opaque memory semantics.
The typical use-case is when there is a single writer thread and one or more reader threads and surrounding loads/stores don't need to be ordered.
This method should be at least fast as
incrementRelease()
since it has weaker memory semantics. So if there is just a single mutator thread, and one or more reader threads, then it is likely you will prefer this method.- Returns:
- the previous value of the counter
- Since:
- 2.1.0
-
incrementPlain
public long incrementPlain()
Increment the counter.This method is not atomic and this can lead to lost-updates due to race conditions. This load and store have plain memory semantics.
The typical use-case for this method is when writer and reader are the same thread.
- Returns:
- the previous value of the counter
- Since:
- 2.1.0
-
decrement
public long decrement()
Perform an atomic decrement that will not lose updates across threads.The loads and store have volatile memory semantics.
- Returns:
- the previous value of the counter
-
decrementOrdered
public long decrementOrdered()
Perform an atomic decrement that is not safe across threads.- Returns:
- the previous value of the counter
- Since:
- 2.1.0
-
decrementRelease
public long decrementRelease()
Decrements the counter non-atomically with release semantics.It can result into lost updates to race condition when called concurrently.
The load has plain memory semantics and the store has release memory semantics.
The typical use-case is when there is one mutator thread, that calls this method, and one or more reader threads.
This method is likely to outperform the
increment()
and probably will be a better alternative.- Returns:
- the previous value of the counter
- Since:
- 2.1.0
-
decrementOpaque
public long decrementOpaque()
Perform a non-atomic decrement using opaque semantics.It can result into lost updates due to race condition when called concurrently.
The load has plain memory semantics and the store has opaque memory semantics.
The typical use-case is when there is a single writer thread and one or more reader threads and surrounding loads and stores don't need to be ordered.
This method should be at least fast as
incrementRelease()
since it has weaker memory semantics. So if there is just a single mutator thread, and one or more reader threads, then it is likely you will prefer this method.- Returns:
- the previous value of the counter
- Since:
- 2.1.0
-
decrementPlain
public long decrementPlain()
Decrements the counter.This method is not atomic and this can lead to lost-updates due to race conditions. This load and store have plain memory semantics.
The typical use-case for this method is when writer and reader are the same thread.
- Returns:
- the previous value of the counter
- Since:
- 2.1.0
-
set
public void set(long value)
Set the counter with volatile semantics.- Parameters:
value
- to be set with volatile semantics.
-
setOrdered
public void setOrdered(long value)
Set the counter with ordered semantics.This method is identical to
setRelease(long)
and that method should be used instead.- Parameters:
value
- to be set with ordered semantics.
-
setRelease
public void setRelease(long value)
Set the counter value atomically.The store has release memory semantics.
- Parameters:
value
- to be set- Since:
- 2.1.0
-
setOpaque
public void setOpaque(long value)
Set the counter value atomically.The store has opaque memory semantics.
- Parameters:
value
- to be set- Since:
- 2.1.0
-
setWeak
public void setWeak(long value)
Set the counter with normal semantics.This method is identical to
setPlain(long)
and that method should be used instead.- Parameters:
value
- to be set with normal semantics.
-
setPlain
public void setPlain(long value)
Set the counter value with plain memory semantics.- Parameters:
value
- to be set with normal semantics.- Since:
- 2.1.0
-
getAndAdd
public long getAndAdd(long increment)
Add an increment to the counter that will not lose updates across threads.- Parameters:
increment
- to be added.- Returns:
- the previous value of the counter
-
getAndAddOrdered
public long getAndAddOrdered(long increment)
Add an increment to the counter with ordered store semantics.This method is identical to
getAndAddRelease(long)
and that method should be used instead.- Parameters:
increment
- to be added with ordered store semantics.- Returns:
- the previous value of the counter
-
getAndAddRelease
public long getAndAddRelease(long increment)
Adds an increment to the counter non-atomically.This method is not atomic; it can suffer from lost-updates due to race conditions.
The load has plain memory semantics and the store has release memory semantics.
The typical use-case is when there is one mutator thread, that calls this method, and one or more reader threads. Typically, this method is combined with the
getAcquire()
to read the value.- Parameters:
increment
- to be added- Returns:
- the previous value of the counter
- Since:
- 2.1.0
-
getAndAddOpaque
public long getAndAddOpaque(long increment)
Adds an increment to the counter non-atomically.This method is not atomic; it can suffer from lost-updates due to race conditions.
The load has plain memory semantics and the store has opaque memory semantics.
The typical use-case is when there is one mutator thread, that calls this method, and one or more reader threads. Typically, this method is combined with a
getOpaque()
to read the value.If ordering of surrounding loads/stores isn't important, then this method is likely to be faster than
getAndAddRelease(long)
because it has less strict memory ordering requirements.- Parameters:
increment
- to be added- Returns:
- the previous value of the counter
- Since:
- 2.1.0
-
getAndAddPlain
public long getAndAddPlain(long increment)
Adds an increment to the counter non-atomically.This method is not atomic; it can suffer from lost-updates due to race conditions.
The load has plain memory semantics and the store has plain memory semantics.
The typical use-case for this method is when writer and reader are the same thread.
- Parameters:
increment
- to be added- Returns:
- the previous value of the counter
- Since:
- 2.1.0
-
getAndSet
public long getAndSet(long value)
Get the current value of a counter and atomically set it to a new value.- Parameters:
value
- to be set.- Returns:
- the previous value of the counter
-
compareAndSet
public boolean compareAndSet(long expectedValue, long updateValue)
Compare the current value to expected and if true then set to the update value atomically.- Parameters:
expectedValue
- for the counter.updateValue
- for the counter.- Returns:
- true if successful otherwise false.
-
get
public long get()
Get the value for the counter with volatile semantics.- Returns:
- the value for the counter.
-
getAcquire
public long getAcquire()
Get the value for the counter with acquire semantics.- Returns:
- the value for the counter.
- Since:
- 2.1.0
-
getOpaque
public long getOpaque()
Get the value for the counter with opaque semantics.- Returns:
- the value for the counter.
- Since:
- 2.1.0
-
getWeak
public long getWeak()
Get the value of the counter using weak ordering semantics. This is the same a standard read of a field.This call is identical to
getPlain()
and that method is preferred.- Returns:
- the value for the counter.
-
getPlain
public long getPlain()
Get the value of the counter using plain memory semantics. This is the same a standard read of a field.- Returns:
- the value for the counter.
- Since:
- 2.1.0
-
proposeMax
public boolean proposeMax(long proposedValue)
Set the value to a new proposedValue if greater than the current value with plain memory semantics.- Parameters:
proposedValue
- for the new max.- Returns:
- true if a new max as been set otherwise false.
-
proposeMaxOrdered
public boolean proposeMaxOrdered(long proposedValue)
Set the value to a new proposedValue if greater than the current value with memory ordering semantics.This method is identical to
proposeMaxRelease(long)
and that method should be used instead.- Parameters:
proposedValue
- for the new max.- Returns:
- true if a new max as been set otherwise false.
-
proposeMaxRelease
public boolean proposeMaxRelease(long proposedValue)
Set the value to a new proposedValue if greater than the current value.This call is not atomic and can suffer from lost updates to race conditions.
The load has plain memory semantics and the store has release memory semantics.
The typical use-case is when there is one mutator thread, that calls this method, and one or more reader threads.
- Parameters:
proposedValue
- for the new max.- Returns:
- true if a new max as been set otherwise false.
- Since:
- 2.1.0
-
proposeMaxOpaque
public boolean proposeMaxOpaque(long proposedValue)
Set the value to a new proposedValue if greater than the current value.This call is not atomic and can suffer from lost updates to race conditions.
The load has plain memory semantics and the store has opaque memory semantics.
The typical use-case is when there is one mutator thread, that calls this method, and one or more reader threads.
This method is likely to outperform
proposeMaxRelease(long)
since this method has less memory ordering requirements.- Parameters:
proposedValue
- for the new max.- Returns:
- true if a new max as been set otherwise false.
- Since:
- 2.1.0
-
toString
public java.lang.String toString()
- Overrides:
toString
in classjava.lang.Object
-
-