StampedLock 支持的三种锁模式:

1.ReadWriteLock 支持两种模式:一种是读锁,一种是写锁

2.StampedLock 支持三种模式,分别是:写锁、悲观读锁和乐观读
1)写锁、悲观读锁的语义和 ReadWriteLock 的写锁、读锁的语义非常类似,
2)允许多个线程同时获取悲观读锁,但是只允许一个线程获取写锁,写锁和悲观读锁是互斥的
3)不同的是:StampedLock 里的写锁和悲观读锁加锁成功之后,都会返回一个 stamp;然后解锁的时候,需要传入这个 stamp
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.StampedLock; class Point {
public static void main(String[] args) throws InterruptedException {
final StampedLock lock = new StampedLock();
Thread T1 = new Thread(()->{
// 获取写锁
lock.writeLock();
// 永远阻塞在此处,不释放写锁
LockSupport.park();
});
T1.start();
// 保证T1获取写锁
Thread.sleep(100);
Thread T2 = new Thread(()->
//阻塞在悲观读锁
lock.readLock()
);
T2.start();
// 保证T2阻塞在读锁
Thread.sleep(100);
//中断线程T2
//会导致线程T2所在CPU飙升
T2.interrupt();
T2.join();
}
}

分析:

1.线程 T1 获取写锁之后将自己阻塞,线程 T2 尝试获取悲观读锁,也会阻塞;

2.此时调用线程 T2 的 interrupt() 方法来中断线程 T2 的话,你会发现线程 T2 所在 CPU 会飙升到 100%。

3.所以,使用 StampedLock 一定不要调用中断操作,
如果需要支持中断功能,一定使用可中断的悲观读锁 readLockInterruptibly() 和写锁 writeLockInterruptibly()

使用 StampedLock的最佳实践demo:

StampedLock 读模板:

import java.util.concurrent.locks.StampedLock;

class Point {
public static void main(String[] args) throws InterruptedException {
final StampedLock sl = new StampedLock(); // 乐观读
long stamp = sl.tryOptimisticRead();
// 读入方法局部变量
......
// 校验stamp
if (!sl.validate(stamp)){
// 升级为悲观读锁
stamp = sl.readLock();
try {
// 读入方法局部变量
.....
} finally {
//释放悲观读锁
sl.unlockRead(stamp);
}
}
//使用方法局部变量执行业务操作
......
}
}

StampedLock 写模板:

import java.util.concurrent.locks.StampedLock;

class Point {
public static void main(String[] args) throws InterruptedException {
final StampedLock sl = new StampedLock();
long stamp = sl.writeLock();
try {
// 写共享变量
......
} finally {
sl.unlockWrite(stamp);
}
}
}

最新文章

  1. refresh的停车场 分类: 栈和队列 2015-06-18 17:13 26人阅读 评论(0) 收藏
  2. Windows文本文件编码
  3. vc如何编译链接opengl库
  4. MD5加密详解
  5. 编写可维护的javascript代码--- 2015.11.21(基本格式化)
  6. 《转》python 网络编程
  7. dfs.replication 参数 动态修改
  8. JavaScript的基本规范
  9. Cisco IP 电话 将它的voice mail 发送到手机
  10. 05-使用jQuery操作input的value值
  11. (转)Java 中正确使用 hashCode 和 equals 方法
  12. URI参数签名算法
  13. 判断Android 当前版本是否为debug版本
  14. Egret里用矢量挖圆形的洞
  15. [No0000100]正则表达式匹配解析过程分析(正则表达式匹配原理)&regexbuddy使用&正则优化
  16. VMware桥接模式下主机和和虚机间互相ping不通的处理方法
  17. oracle 分页的sql语句
  18. centos6.5 源码安装 mysql
  19. Centos6_32位系统512M内存_如何安装gogs_Mysql_配置开机自启动
  20. HUD-5379

热门文章

  1. 记录 springboot 整合swagger2 出现documentationPluginsBootstrapper&&NullPointerException异常
  2. git学习资料汇总
  3. 在idea中查看jar包源码
  4. 第三周day2
  5. Python占位符总结:%方式和format方式
  6. Vue之使用umy-ui库的u-table解决 el-table当存在大量数据时,界面操作卡顿。
  7. Flink 消费RabbitMQ 和 Kafka
  8. spring boot2 jpa分页查询百万级数据内存泄漏
  9. ESP32-IDF 在vscode环境搭建
  10. vue调接口导出表格