ArticleDirectory
- When to use atomicreference
- Atomicreference
- Atomicreference
- Get
- Set
- Lazyset
- Compareandset
- Weakcompareandset
- Getandset
- Tostring
TheAtomicintegerClass has a number of uses, but one is a drop-in replacement for an atomic counter.Before Java 5, we had to write classes with access to the counter variable inSynchronizedBlocks or methods, Or else useVolatileVariable which is a lighter form of synchronization but with the risk that some updates cocould be missed if they happen concurrently.AtomicintegerCan be used as a drop-in replacement that provides the best of both worlds:
Public class counter {private atomicinteger COUNT = new atomicinteger (0); Public void incrementcount (){Count. incrementandget ();} Public int getcount (){Return count. Get ();}}
The significant featureAtomicintegerWhich we exploit is the callIncrementandget (). This method wraps round a machine instruction (or instructions) similar to CAs whichWill read, increment and set the underlying value in memory as a 'locked together '(atomic) Action (It means only one thread can access this compound actions. So we can observe it is thread safety). Notice that this method returns the new incremented value, although we ignore it. On the other hand, if we were usingAtomicintegerTo do something like provide the next key to store in a database, we wowould probably want to take notice of the return value.
Unsurprisingly,AtomiclongProvides similar atomic access to an underlyingLongVariable.
On this page, we look at atomicreference classes that can be useful when you want to couple more than piece of data together and access them atomically.
Note that the classes on this page are probably less usedAtomicintegerAndAtomiclong. On the following page, we will discuss a much more important part of the Java concurrency framework, namely the concurrenthashmap class.
Atomicreference
TheAtomicreferenceClass provides a way to atomically read and set an object reference. It is generally usedTie together more than one atomically accessed variableBy wrapping them inImmutable object instance(That is, one whose fields areFinal).
Suppose, for example, that in a web server application, we want to count the number of page accesses and also the number of accesses that failed due to an error. we can do this by creating a class to encapsulate the current statistics, and then create and updateAtomicreferenceTo an instance of this class:
Public Class Accessstatistics { Private Final Int Nopages, noerrors; Public Accessstatistics ( Int Nopages, Int Noerrors ){ This . Nopages = Nopages; This . Noerrors = Noerrors ;} Public Int Getnopages (){ Return Nopages ;} Public Int Getnoerrors (){ Return Noerrors ;}}
Now, to update the statistics, we can use a method such as the following:
Private Atomicreference <accessstatistics> stats = New Atomicreference <accessstatistics> ( New Accessstatistics (0, 0 )); Public Void Incrementpagecount ( Boolean Waserror) {accessstatistics Prev, newvalue; Do {Prev = Stats. Get (); Int Nopages = Prev. getnopages () + 1 ; Int Noerrors = Prev. getnoerrors; If (Waserror) {noerrors ++ ;} Newvalue = New Accessstatistics (nopages, noerrors );} While (! Stats. compareandset (prev, newvalue ));}
Atomic references (and atomic classes in general) have the same memory semantics as volatile Variables. So when the reference to the newAccessstatisticsIs set toAtomicreference, At that moment, the JVM must ensure that the variables set during the constructor are visible to other threads. in other words, any write to volatile or atomic references variables can be observed by the other threads. it isn' t strictly necessary in this case to make the fields onAccessstatisticsFinal. Nonetheless, it's good practice to Mark Fields on immutable classes as final, and we do so here.
When to use atomicreference
atomic reference shocould be used in a setting where you need to do simple atomic (I. E ., thread safe, non-trivial) operations on a reference, for which monitor-based synchronization is not appropriate. suppose you want to check to see if a specific field only if the State of the object remains as you last checked :
Atomicreference <Object> cache = newatomicreference <Object>(); Object cachedvalue=Newobject (); cache. Set (cachedvalue );//... Time passes...Object cachedvaluetoupdate =Cache. Get ();//... Do some work to transform cachedvaluetoupdate into a new versionObject newvalue =Somefunctionofold (cachedvaluetoupdate );BooleanSuccess = cache. compareandset (cachedvalue, cachedvaluetoupdate );
Because of the atomic reference semantics, you can do this even ifCache
Object is shared amongst threads, without usingSynchronized
. In general, you're better off using synchronizers orJava. util. Concurrent
Framework rather than bareAtomic *
Unless you know What you're re doing.
Two excellent dead-tree references which will introduce you to this topic: Herlihy's excellent art of Multiprocessor programming and Java concurrency in practice.
Note that (I don't know if this has always been true) Reference Assignment (I. e .,=
) Is itself atomic (for everything than T perhapsDouble
AndLong
) Without explicitly usingAtomic *
. See the JLS 3ed, section 17.7,
Other uses Atomicreference
TheAtomicreferenceClass can also be useful in cases where you have a structure which is basically read-only but which you very occasionally want to update. on the occasional update, you can replace the old copy with a brand new copy.
Atomicreference
PublicAtomicreference(V initialvalue)
-
Creates a new atomicreference with the given initial value.
-
Parameters:
-
Initialvalue
-The Initial Value
Atomicreference
PublicAtomicreference()
-
Creates a new atomicreference with null initial value.
Get
Public final vGet()
-
Gets the current value.
-
-
-
Returns:
-
The current value
Set
Public final voidSet(V newvalue)
-
Sets to the given value.
-
-
-
Parameters:
-
Newvalue
-The new value
Lazyset
Public final voidLazyset(V newvalue)
-
Eventually sets to the given value.
-
-
-
Parameters:
-
Newvalue
-The new value
-
Since:
-
1.6
Compareandset
Public final BooleanCompareandset(V CT, V update)
-
Atomically sets the value to the given updated value if the current value
=
The expected value.
-
-
-
Parameters:
-
Secondary CT
-The expected value
-
Update
-The new value
-
Returns:
-
True if successful. False return indicates that the actual value was not equal to the expected value.
Weakcompareandset
Public final BooleanWeakcompareandset(V CT, V update)
-
Atomically sets the value to the given updated value if the current value
=
The expected value.
May fail spuriously and does not provide ordering guarantees, so is only rarely an appropriate alternativeCompareandset
.
-
-
-
Parameters:
-
Secondary CT
-The expected value
-
Update
-The new value
-
Returns:
-
True if successful.
Getandset
Public final vGetandset(V newvalue)
-
Atomically sets to the given value and returns the old value.
-
-
-
Parameters:
-
Newvalue
-The new value
-
Returns:
-
The previous value
Tostring
Public StringTostring()
-
Returns the string representation of the current value.
-
-
Overrides:
-
Tostring
In Class
Object
-
-
Returns:
-
The string representation of the current value.