StampedLock的简单用法
来源:互联网 发布:海知智能 编辑:程序博客网 时间:2024/06/11 00:21
StampedLock是JDK1.8新引入的锁机制,可以简单的理解为读写锁的改进版本。我们知道读写锁可以让读和读之间完全并发,但是读和写之间是有阻塞的。StampedLock使用了一种乐观锁的读策略,这种机制类似于无锁的概念,使得获取锁的过程中不会阻塞写线程。
简单例子
下面给出一个JDK官方给的Demo:
public class Point {private double x, y;private final StampedLock sl = new StampedLock();void move(double deltaX, double deltaY) {long stamp = sl.tryWriteLock();try {x += deltaX;y += deltaY;} finally {sl.unlockWrite(stamp);}}double distanceFromOrigin() {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);}}上面是一个点移动的一个抽象。首先对于move()操作,加锁和解锁的过程和普通的Lock类似。对于distanceFromOrigin(),首先会使用tryOptimisticRead()加一个乐观读锁,此时会返回一个stamp数值。获取到X和Y的值之后,去验证其有效性,如果尚未被修改过,那么读取成功,计算结果返回。如果验证失败,那么会加读锁。
在这个例子中,使用的锁升级,里面调用了readLock()方法去操作。这个操作会有一个循环的CAS操作,直到获取到锁为止。
StampedLock的缺陷
在使用StampedLock的过程中,如果API使用的不当,则有可能造成CPU占用率过高。
// 获取读锁(阻塞,不响应中断)long readLock();// 获取读锁(立即)long tryReadLock();// 限时获取读锁(响应中断)long tryReadLock(long time, TimeUnit unit);// 获取读锁(阻塞,响应中断)long readLockInterruptibly();StampedLock在使用readLock()的时候,使用的是Unsafe.park()函数。park()在遇到线程中断时,会直接返回。这就导致阻塞在park()上面的线程被中断后,会再次进入循环,从而导致CPU的大量占用。以下是事例代码:
public class StampedLockCPUDemo {static Thread[] holdCpuThreads = new Thread[3];static final StampedLock lock = new StampedLock();public static void main(String[] args) throws InterruptedException {new Thread() {@Overridepublic void run() {long readLong = lock.writeLock();LockSupport.parkNanos(600000000000L);lock.unlockWrite(readLong);}}.start();Thread.sleep(100);for (int i = 0; i < 3; ++i) {holdCpuThreads[i] = new Thread(new HoldCPUReadThread());holdCpuThreads[i].start();}Thread.sleep(10000);// 线程中断后,会占用CPUfor (int i = 0; i < 3; ++i) {holdCpuThreads[i].interrupt();}}private static class HoldCPUReadThread implements Runnable {@Overridepublic void run() {long lockr = lock.readLock();System.out.println(Thread.currentThread().getName() + "获得读锁");lock.unlockRead(lockr);}}}笔者在自己的电脑上面测试时,CPU的占用率如下:
参考:《Java高并发程序设计》
链接:http://moguhu.com/article/detail?articleId=44
阅读全文
1 0
- StampedLock的简单用法
- Java 8的StampedLock
- StampedLock的使用
- StampedLock
- (转载)StampedLock、ReadWriteLock以及synchronized的比较
- Java8对读写锁的改进:StampedLock
- Bug:StampedLock的中断问题导致CPU爆满
- Java 8:StampedLock,ReadWriteLock以及synchronized的比较
- Java多线程synchronized、ReentrantLock、ReentrantReadWriteLock 和StampedLock 的对比
- java8-StampedLock
- vi的简单用法
- fstream的简单用法
- namespace的简单用法
- qmake的简单用法
- AJAX的简单用法
- apt的简单用法
- JScrollPane的简单用法!
- iframe的简单用法
- 中缀表达式转后缀表达式(又称逆波兰式)
- Convert Sorted List to Binary Search Tree
- 清除匿名定时器
- CodeForces 136 A.Presents(水~)
- tensorflow1.3.0安装注意
- StampedLock的简单用法
- 谈谈刚被西数吞并的闪存公司——Tegile System
- java实现二叉树,以及二叉树的遍历和先序和后序求解
- 编码格式简介:ASCII码、ANSI、GBK、GB2312、GB18030和Unicode、UTF-8,BOM头
- PATbasic1004
- 方向梯度直方图(HOG,Histogram of Gradient)
- 【Mybatis】——foreach使用方式
- bzoj 4574: [Zjoi2016]线段树 动态规划
- 石家庄一中游记(2017暑假)