Home >Java >javaTutorial >Interpretation of new features of Java8--StampedLock

Interpretation of new features of Java8--StampedLock

零下一度
零下一度Original
2017-06-17 14:15:031422browse

This article conducts a comparative analysis from synchronized, Lock to the new StampedLock in Java8. Friends who are interested in the new features of Java8, StampedLock, should take a look.

Java8 is like a treasure, a small API Improvements are enough to write an article. For example, synchronization has always been an old topic in multi-threaded concurrent programming. I believe no one likes synchronized code. This will reduce the throughput and other performance indicators of the application. In the end, When it is bad, it will hang and crash, but even then you have no choice because you have to ensure the accuracy of the information. Therefore, this article decided to conduct a comparative analysis from synchronized, Lock to the new StampedLock in Java 8. I believe that StampedLock will not disappoint everyone.

synchronizedBefore java5, synchronization was mainly achieved using synchronized. It is a keyword in the Java language. When it is used to modify a method or a code block, it can ensure that at most one thread executes the code at the same time.

There are four different synchronized blocks:

1. Instance method

2. Static method

3. Instance method Synchronized block in

4. Synchronized block in static method

Everyone should be familiar with this, so I won’t go into more details. The following is a code example

synchronized(this)
// do operation
}

Summary: Synchronized has always been a veteran role in multi-threaded concurrent programming. Many people will call it a heavyweight lock. However, with various optimizations of Synchronized in Java SE1.6, the performance has improved. Also improved.


LockIt is added by Java 5 in java.util.con

current

.locks an API. Lock is an interface. The core methods are lock(), unlock(), and tryLock(). The implementation classes include ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock;


ReentrantReadWriteLock, ReentrantLock and synchronized locks have the same memory semantics.

Different from synchronized, Lock is entirely written in Java and has nothing to do with JVM implementation at the Java level. Lock provides a more flexible locking mechanism, and many features that synchronized does not provide, such as lock voting, timed lock waiting and interrupt lock waiting, but because lock is implemented through code, to ensure that the lock will be released, you must unLock( ) into finally{}

The following is a code example of Lock

rwlock.writeLock().lock();
try {
// do operation
} finally {
rwlock.writeLock().unlock();
}

Summary: A more flexible and scalable lock than synchronized mechanism, but anyway synchronized code is easier to write

StampedLockIt is java8 in java.util.concurrent.locks A new API has been added.


ReentrantReadWriteLock can only obtain the write lock when there is no read-write lock. This can be used to implement pessimistic reading (Pessimistic Reading), that is, if reading is performed during execution, there may often be Another implementation needs to write, in order to maintain synchronization, the read lock of ReentrantReadWriteLock can come in handy.


However, if there are many reads and few writes, using ReentrantReadWriteLock may cause the writing thread to encounter a starvation problem, that is, the writing thread cannot compete. Waiting until locked.

StampedLock control lock has three modes (write, read, optimistic read). A StampedLock state is composed of two parts: version and mode. The lock acquisition method returns a number as the ticket stamp, which uses the corresponding lock state Indicates and controls access, and the number 0 indicates that no write lock is authorized for access. Read locks are divided into pessimistic locks and optimistic locks.


The so-called optimistic read mode, that is, if there are many read operations and few write operations, you can be optimistic that the probability of writing and reading happening at the same time is very small, so Using a full read lock without pessimism, the program can check whether the data has been changed by writing after reading the data, and then take subsequent measures (reread the change information, or

throw an exception

) , this small improvement can greatly improve the throughput of the program! ! The following is an example of StampedLock provided by java doc

class Point {
 private double x, y;
 private final StampedLock sl = new StampedLock();
 void move(double deltaX, double deltaY) { // an exclusively locked method
  long stamp = sl.writeLock();
  try {
  x += deltaX;
  y += deltaY;
  } finally {
  sl.unlockWrite(stamp);
  }
 }
 //下面看看乐观读锁案例
 double distanceFromOrigin() { // A read-only method
  long stamp = sl.tryOptimisticRead(); //获得一个乐观读锁
  double currentX = x, currentY = y; //将两个字段读入本地局部变量
  if (!sl.validate(stamp)) { //检查发出乐观读锁后同时是否有其他写锁发生?
  stamp = sl.readLock(); //如果没有,我们再次获得一个读悲观锁
  try {
   currentX = x; // 将两个字段读入本地局部变量
   currentY = y; // 将两个字段读入本地局部变量
  } finally {
   sl.unlockRead(stamp);
  }
  }
  return Math.sqrt(currentX * currentX + currentY * currentY);
 }
//下面是悲观读锁案例
 void moveIfAtOrigin(double newX, double newY) { // upgrade
  // Could instead start with optimistic, not read mode
  long stamp = sl.readLock();
  try {
  while (x == 0.0 && y == 0.0) { //循环,检查当前状态是否符合
   long ws = sl.tryConvertToWriteLock(stamp); //将读锁转为写锁
   if (ws != 0L) { //这是确认转为写锁是否成功
   stamp = ws; //如果成功 替换票据
   x = newX; //进行状态改变
   y = newY; //进行状态改变
   break;
   }
   else { //如果不能成功转换为写锁
   sl.unlockRead(stamp); //我们显式释放读锁
   stamp = sl.writeLock(); //显式直接进行写锁 然后再通过循环再试
   }
  }
  } finally {
  sl.unlock(stamp); //释放读锁或写锁
  }
 }
 }

Summary: StampedLock is cheaper than ReentrantReadWriteLock, which means the consumption is relatively small.

Performance comparison between StampedLock and ReadWriteLockThe following figure shows that compared with ReadWritLock, in the case of one thread, the reading speed is about 4 times that of , writing is 1x.

The figure below shows that with six threads, the read performance is dozens of times higher, and the write performance is also nearly 10 times:

The following figure shows the throughput improvement:

Summary

1. Synchronized is implemented at the JVM level. Not only can synchronized be monitored through some monitoring tools lock, and if an exception occurs during code execution, the JVM will automatically release the lock;

2, ReentrantLock, ReentrantReadWriteLock, and StampedLock are all locks at the object level. It is necessary to ensure that the lock will be To release, you must put unLock() in finally{};

3. StampedLock has a huge improvement in throughput, especially in scenarios where there are more and more reading threads;

4. StampedLock has a complex API. For locking operations, it is easy to misuse other methods;

5. When there are only a few competitors, synchronized is a good general lock implementation;

6. When thread growth can be estimated, ReentrantLock is a good general-purpose lock implementation;

The above is the detailed content of Interpretation of new features of Java8--StampedLock. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn