StampedLock比读写锁更快的锁

妖狐艹你老母 2022-01-15 00:55 334阅读 0赞

在JDK8的年代,出现了一名绝世高手,他在读多写少速度大会上击败了老牌的昔日冠军读写锁。

他就是StampedLock。

出现的情况,更好的解决并发下的读多写少,提高性能。

StampedLock支持三种模式,分别是:写锁,悲观读锁,和乐观读。其中,他拥有着读写锁相近的功力,不同的是:StampedLock的写锁和悲观读锁加锁成功之后,都会返回一个long类型的stamp,然后解锁的时候,需要传入这个stamp。

为什么StampedLock性能之所以比读写锁好,原因在于StampedLock支持乐观读的方式,而读写锁支持多个线程同时读,所有的写操作会被阻塞,而StampedLock提供的乐观读,是允许一个线程能获取写锁的,也就是说不是所有的写操作都被阻塞,这就是关键的地方。

同时有需要注意的事项的地方:

StampedLock的功能是读写锁的子集。所以StampedLock适用场景就是单纯的读多写少。

StampedLock并且是不可重入的。即需要特别注意

StampedLock的悲观读锁,写锁不支持条件变量。

如果某个线程阻塞在读锁或者写锁上,如果此时调用了这个线程的interrupt方法,会导致这个线程所在的cpu100%,所以处理这类情况,最好一定不要调用中断操作,如果需要支持中断,一定使用可中断的悲观读锁的readLockInterruptibly() 和写锁 writeLockInterruptibly()。规则。

赴上自己的demo:

  1. package com.hnist.lzn.thread;
  2. public class StampedLock {
  3. private final java.util.concurrent.locks.StampedLock sl = new java.util.concurrent.locks.StampedLock();
  4. private int x;
  5. //写锁
  6. void modify(int a){
  7. long stamp = sl.readLock();
  8. try{
  9. setX(a);
  10. int ax = getX();
  11. System.out.println("----------------------------------------------------写互斥,修改后a:"+ax);
  12. }finally {
  13. sl.unlock(stamp);
  14. }
  15. }
  16. //读模板
  17. void read(){
  18. long stamp = sl.tryOptimisticRead();
  19. int num = getX();
  20. //检验stamp
  21. if (!sl.validate(stamp)){
  22. //无效升级为悲观读锁
  23. stamp = sl.readLock();
  24. try {
  25. num = getX();
  26. System.out.println("*****************************悲观读数据");
  27. }finally {
  28. sl.unlock(stamp);
  29. }
  30. }
  31. //都是操作变量的业务
  32. System.out.println("通过读方法:"+num);
  33. }
  34. public void setX(int x){
  35. this.x = x;
  36. }
  37. public int getX(){
  38. return x;
  39. }
  40. public static void main(String[] args) throws InterruptedException {
  41. StampedLock stampedLock = new StampedLock();
  42. Thread th1 = new Thread(()->{
  43. //读线程
  44. while(true){
  45. stampedLock.read();
  46. }
  47. });
  48. Thread th4 = new Thread(()->{
  49. //读线程
  50. while(true){
  51. stampedLock.read();
  52. }
  53. });
  54. Thread th2 = new Thread(()->{
  55. //写线程
  56. int i = 9999999;
  57. while(true) {
  58. stampedLock.modify(i--);
  59. }
  60. });
  61. Thread th3 = new Thread(()->{
  62. //写线程
  63. int i = 1;
  64. while(true) {
  65. stampedLock.modify(i++);
  66. }
  67. });
  68. //th2.start();
  69. th3.start();
  70. th4.start();
  71. //Thread.sleep(200);
  72. th1.start();
  73. //Thread.sleep(1000);
  74. // Thread.sleep(1000);
  75. }
  76. }

发表评论

表情:
评论列表 (有 0 条评论,334人围观)

还没有评论,来说两句吧...

相关阅读

    相关 互斥

    一、线程互斥方式。 --- 互斥锁 1、什么是互斥锁?特点怎么样? 互斥锁是专门用于处理线程之间互斥的一种方式,它有两种:上锁状态/解锁状态。 如果互斥锁处于上锁状