No one likes syncing code, which lowers performance metrics like your app's throughput, and hangs up in the worst of times, but even then you don't have much choice.
Many theories and patterns to achieve multi-threaded synchronization access to a resource, the most famous commonly used is the read-write lock Readwritelock, it is through blocking to reduce multi-threaded consumption of a resource-induced competition, in theory sounds good, but in reality the lock means slow performance, especially with a large number of write threads in the case.
Java 8 introduces a new read-write lock called Stampedlock. Not only is this lock faster, but it also provides a powerful optimistic lock API, which means you can get a read lock at a lower price, and hopefully no write operation occurs during this time, and when this time is done, you can check the lock to see if there is a write operation happening in the time just now? Then you can decide if you need to try again or upgrade the lock or discard it.
Usually our sync lock is the following code:
Synchronized (This)
Do operation
}
The Reentrantlock code provided by Java 6 is as follows:
Rwlock.writelock (). Lock ();
try {
Do operation
} finally {
Rwlock.writelock (). Unlock ();
}
Reentrantreadwritelock, Reentrantlock, and synchronized locks have the same memory semantics, and synchronized code is easier to write anyway. Reentrantlock code must be written in strict accordance with this, otherwise it will cause serious problems.
Stampedlock is cheaper than Reentrantreadwritelock, which is less expensive.
Stampedlock control lock has three modes, a Stampedlock state is composed of version and mode two parts, the lock acquisition method returns a number as a ticket stamp, which is represented with the corresponding lock state and control access, the number 0 indicates that no write lock is authorized to access. In the reading lock is divided into pessimistic lock and optimistic lock.
Here is the code application for Stampedlock:
public class Bankaccountwithstampedlock {
Private final Stampedlock lock = new stampedlock ();
private double balance;
public void deposit (double amount) {
long stamp = Lock.writelock ();
try {
Balance = balance + amount;
} finally {
Lock.unlockwrite (stamp);
}
}
Public Double GetBalance () {
Long stamp = Lock.readlock ();
try {
return balance;
} finally {
Lock.unlockread (stamp);
}
}
}
If we are going to implement a cross-field invariant access, such as the following mypoint the X and y two variables must be incremented simultaneously, this requires an exclusive lock:
public class MyPoint {
Private double x, y;
Private final Stampedlock SL = new stampedlock ();
method is modifying x and Y, needs exclusive lock
public void Move (double deltax, double deltay) {
long stamp = Sl.writelock ();
try {
x + = DeltaX;
Y + = DeltaY;
} finally {
Sl.unlockwrite (stamp);
}
}
For conditional state changes, the read lock needs to be converted to a write lock, as shown in the following code:
public void Moveifat (double oldx, double OldY, double newx, double newy) {
Long stamp = Sl.readlock (); Get a read pessimistic lock
try {
while (x = = Oldx && y = = OldY) {//loop, check that the current state is compliant
Long Writestamp = Sl.tryconverttowritelock (stamp);//convert read lock to write lock
if (writestamp! = 0L) {//This is the confirmation that the write lock was successful
Stamp = Writestamp; If the ticket is successfully replaced
x = newx; y = newy; Make a state change
Break
} else {//If it cannot be successfully converted to a write lock
Sl.unlockread (stamp);//We explicitly release the read lock
Stamp = Sl.writelock (); Explicitly write the lock directly and then try again by looping
}
}
} finally {
Sl.unlock (stamp); Release a read or write lock
}
}
The above is pessimistic reading lock case, the following look at optimistic reading lock case:
Public double Distancefromorigin () {
long stamp = Sl.tryoptimisticread (); Get an optimistic read lock
double currentx = x, currenty = y; Read two fields into local local variables
if (!sl.validate (stamp)) {//check that an optimistic read lock is issued and is there any other write lock occurring?
Stamp = Sl.readlock ();//If not, we get a read pessimistic lock again
try {
CurrentX = x;//reads two fields into local local variables
CurrentY = y;
} finally {
Sl.unlockread (stamp); Release Read lock
}
}
Return math.sqrt (CurrentX * currentx + currenty * currenty);
}
Http://www.jdon.com/idea/java/java-8-stampedlock.html
Stampedlock of Java 8