List of high-quality authors
J**A Concurrency Basics: A Comprehensive Analysis of AtomicMarkableReference for Atomic Classes - Programmer Goodatomicmarkablereference
Classes can ensure the atomicity update of references and Boolean flags, effectively avoid race conditions in multi-threaded environments, and provide methods to easily implement condition-based atomicity operations, improving the concurrency security and reliability of programs.
atomicmarkablereference
Classes associate a Boolean tag with a reference and can update the pair atomically, so in a multithreaded environment, you can be sure that the update of the tag and reference happens as an inseparable operation, without intermediate state being observed by other threads.
Simulate a business scenario, suppose, there is a ** shopping platform, in which there is a very important business is inventory management, in this system, each commodity has an inventory quantity, when the inventory quantity is zero, the product can no longer be purchased, however, because the system is highly concurrent, there may be multiple threads (may be multiple users at the same time to initiate a purchase request) at the same time to try to reduce the inventory of the same product.
In this case, it can be usedatomicmarkablereference
To solve this problem, you can encapsulate the inventory quantity in an object and use itatomicmarkablereference
to refer to this object, a marker bit can be used to indicate whether the inventory quantity has been "locked" by another thread to decrease.
When a thread tries to reduce the inventory, it will first check the marker bit, if the marker bit indicates that the inventory is not locked, then the thread will try to atomically set the marker bit to the "locked" state, and get the current inventory quantity, if successful, the thread can safely reduce the inventory without worrying about other threads modifying it at the same time, after reducing the inventory, the thread will atomically clear the marker bit, indicating that the inventory can now be locked and modified by other threads.
If an attempt to lock the inventory fails (because another thread has already locked it), then the thread can choose to retry, wait, or return an error message to the user, by using itatomicmarkablereference
to ensure the correctness and consistency of inventory quantities in a high-concurrency environment and avoid overselling.
atomicmarkablereference
Classes are primarily used to solve data consistency problems in concurrent environments, especially when it is necessary to atomically update the state of a reference and its associated (usually represented by a Boolean tag), and can often be used to solve problems similar to the following:
Lock-free data structures: In the implementation of lock-free (lock-free
) or based on optimistic locks (optimistic locking
) data structureatomicmarkablereference
It can be used to atomically update the reference and state of a node. Status tracking: Can be used when you need to track the state of an objectatomicmarkablereference
。For example, there might be an object that needs to be shared across multiple threads, and you need to know if the object has already been processed by storing the object and a tag (representing the processing state) in itatomicmarkablereference
you can ensure the atomicity of operations when inspecting and processing objects. Cache coherence: When building a caching systematomicmarkablereference
This can be used to ensure that cached entries are updated atomically, for example, when cached entries need to be invalidated or updated, tags can be used to indicate the validity of the entries and usedatomicmarkablereference
to atomically update entries and tags. Avoid ABA problems: When using a comparison based and swap (compare-and-swap, cas
When you operate atomic classes, you may run into the so-called ABA problem, which means that a variable has a original value of a, and then another thread changes it to b and then changes it back to a, so the thread that checks this variable with cas will find that its value has not changed, but in fact it has been modified by other threads. atomicmarkablereference
This problem is avoided by introducing an additional marker bit, because a change in the marker bit can be used to detect a state change in the middle, even if the referenced value does not change. Here's a simple j**a** that demonstrates how to use itatomicmarkablereference
Class:
import j**a.util.concurrent.atomic.atomicmarkablereference;
public class atomicmarkablereferencedemo
In the ** above, one was created firstatomicmarkablereference
instance, the default value is a string"hello"and markersfalse
, usecompareandset
The method attempts to update the reference and tag atomically if the current value is equal to"hello"and marked asfalse
, it is updated to"world"withtrue
, which returns a boolean value indicating whether the reference and tag were successfully updated, and then used againcompareandset
The method tries to update based on a different old value and tag, but this time the update fails because the current value or tag doesn't match as expected, and finally, gets and prints the current value and tag again to confirm that they didn't fail because they failedcompareandset
call and change.
atomicmarkablereference
The implementation principle mainly relies on the underlying hardware support, especially the comparison and exchange of atomicity (compare-and-swap, cas
) operation. Cas manipulation is a lock-free algorithm that allows multiple threads to securely manipulate shared data without the use of locks.
Inatomicmarkablereference
, cas operations are used to ensure that simultaneous updates of references and tags are atomic, specificallyatomicmarkablereference
Two fields are maintained internally: one is a referenced object and the other is a Boolean tag, and the updates of both fields are atomic, which is achieved through cas operations.
But,atomicmarkablereference
Instead of using a single cas operation to update both the reference and the tag, in fact, it uses two separate cas operations, and there needs to be some way between the two operations to ensure atomicity, which is usually achieved by using a loop internally, which goes on until both the reference and the tag are updated successfully, or until it is determined that the update is unlikely to succeed.
In order to ensure atomicity,atomicmarkablereference
A technique called "double cas" or "double check locking" is employed, which involves two steps: first check if the current values of the references and tags match the expected values, and if they do, perform a CAS operation to try to update them, and if in the process, either value changes (due to concurrent modifications by other threads), then the update fails and needs to be tried again.
At the heart of the underlying algorithm are two CAS operations: one to update the reference and the other to update the marker, both of which need to meet certain conditions to succeed. When trying to update a reference, you need to make sure that the current tagged value matches the expected tagged value; Similarly, when attempting to update a tag, you need to make sure that the current reference value matches the expected reference value.
However, these two cas operations are not completely independent, they are grouped together in such a way as to ensure that no interference by other threads occurs between the update of references and tags, which is usually achieved by using a loop internally that attempts to update references and tags until it succeeds or determines that it cannot succeed (e.g., a condition is no longer met due to concurrent modifications by other threads).
Summary:atomicmarkablereference
class by taking advantage of the underlyingCAS operationsAs well as oneA technique known as "double CAS" or "double check locking".to implement atomic updates to references and tags in a concurrent environment. However, it is important to note that not all methods are atomic (egset
method), you need to take special care when using it to ensure thread safety.
Here it is:atomicmarkablereference
Meaning of the primary method in the class:
atomicmarkablereference(v initialref, boolean initialmark)
constructor, which is used to create a new oneatomicmarkablereference
instance, set the initial reference value and tags. v getreference()
Gets the currently referenced object. boolean ismarked()
Gets the value of the current tag. void set(v newreference, boolean newmark)
Set up new reference values and tags, note that this method is not atomic; It sets the reference first, then the flag, which should be used if atomicity is requiredcompareandset
Method. boolean weakcompareandset(v expectreference, v newreference, boolean expectedmark, boolean newmark)
Sets the values of references and tags atomically, but allows for greater concurrency if the current reference is equal toexpectreference
and the current tag is equal toexpectedmark
, it is updated tonewreference
withnewmark
, this approach may fail more frequently and require a loop retry, but it will be less intrusive to the rest of the system. boolean compareandset(v expectreference, v newreference, boolean expectedmark, boolean newmark)
Atomically sets the values of the reference and tag if the current reference is equal toexpectreference
and the current tag is equal toexpectedmark
, it is updated tonewreference
withnewmark
, which provides strong consistency guarantees. boolean attemptmark(v expectedreference, boolean newmark)
If the current reference is equal toexpectedreference
, the marker is set atomically asnewmark
。These methods provide atomic operations on tagged references that can be safely used in a multithreaded environmentcompareandset
Methods are one of the most commonly used methods in this class because it provides a way to update references in a thread-safe way, only when the current values of references and tags match the expected values.
Note:set
Methods can set new references and tags, but it doesn't provide atomicity guarantees, and should be used if you need to keep them atomicity when setting references and tagscompareandset
orweakcompareandset
Method.
J**A Concurrency Basics: A Comprehensive Analysis of AtomicMarkableReference for Atomic Classes - Programmer Goodatomicmarkablereference
The advantage of the class is that it can ensure the atomicity update of references and tags in a multi-threaded environment, effectively avoiding race conditions, improving the concurrency safety of the program, and its use is relatively simple and intuitivecompareandset
and other methods can easily implement conditional updates based on old values.
It takes up more space than a normal atomic reference because it requires an additional tag to be stored, which can be a performance overhead in high concurrency scenarios due to the need to update both the reference and the tag.
It is recommended when you need to maintain a reference in a concurrent environment and update it atomically based on a condition (represented by a tag).atomicmarkablereference
However, in scenarios where performance is extremely demanding or memory usage sensitive, you may need to weigh the overhead and benefits of using other synchronization mechanisms or data structures.
Follow me and learn Internet programming techniques every day - programmer Goode end!end!end!