关于Java的StampedLock类

我将描述学习Java 8的StampedLock类,这是为了练习而学习的。但我只提及其中的一些方法。

基本(#1)

这个类有三种模式,并且可以通过操作每个模式来限制方法的访问。而操作每个模式使用了一个叫做”stamp”的东西。”stamp”是一个整数,使用long类型。

写作

    • writeLock()メソッド・・・排他的にアクセスをブロックする。戻り値:スタンプ

 

    unlockWrite(long)メソッド・・・上記ブロックの解除。

阅读

    • ReadLock()メソッド・・・排他的ではなくアクセスをブロックする。戻り値:スタンプ

 

    unlockRead(long stamp)メソッド・・・上記ブロックの解除。

乐观阅读

    • tryOptimisticRead()メソッド・・・排他的ロックが掛かっていれば0を返す。それ以外の場合はstampを返す。

 

    validate(long stamp)メソッド・・・ロックがかかっていなければtrueを返す。スタンプが0ならfalseを返す。

根据公式文件,该模式被认为是脆弱的,并且只能通过writing模式来访问。建议仅将其用于read字段。
对于上述每个模式,都有一个用于升级的转换方法。

尝试将其转换为写锁(tryConvetToWriteLock) – 如果已经有写锁,则返回stamp;如果有读锁但没有写锁,则解锁读锁并加上写锁,然后返回stamp;如果处于乐观读状态且立即可以访问,则返回写stamp;否则返回0。

如果有写锁被获取到,则解除该写锁并获取读锁。如果有读锁被获取到,则返回 stamp。如果有乐观读锁被获取到,并且可以立即获取读锁,则获取读锁并返回 stamp。除以上情况外,则返回 0。

尝试转换为乐观读取(long stamp)-
如果有任何锁定存在,则释放该锁定并返回乐观读取的时间戳。如果处于乐观读取状态,则返回该时间戳。如果不符合以上情况,则返回0。

StampedLock是一個有效的類別,當用於多線程時時非常有用。如果應用程序運行超過一年,則可以再次使用當前stamp。可以通過isReadLock(),isWriteLock()和getReadLockCount()進行確認是否有鎖定。

public class Main{
 public static void main(String[] args){

  StampledLockTest stampledLockTest = new StampledLockTest();

  testThread testThread = new testThread();

  testThread.start();

  testThread.run();
 }
}

public class testThread extends Thread{
 StampledLockTest stampledLockTest = new StampledLockTest();

 testThread(){}

 public void run(){
  for(int i=0; i<10; i++){
   stampledLockTest.writeLockTest();
   //stampledLockTest.readLockTest();
   try{
      sleep(100);
   }catch(InterruptedException e){
      e.printStackTrace();
   }
   }
  }
 }
}


import java.util.concurrent.locks.StampedLock;

public class StampledLockTest{
 public static void main(String[] args){

  StampedLock sLock  = new StampedLock();
  long time = System.currentTimeMills();

  public int number;
  public StampledLockTest() {this.number=0;}

  public void writeLockTest(){

        long stamp = sLock.writeLock();

        number++;

        sLock.unlockWrite(stamp);

        System.out.println(number);
    }

  public void readLockTest(){

        long stamp = sLock.readLock();
                System.out.println(System.currentTimeMillis()-time+"time");
        number++;
                System.out.println(System.currentTimeMillis()-time+100+"time");
        sLock.unlockRead(stamp);
                System.out.println(System.currentTimeMillis()-time+1000+"time");
        System.out.println(number);
    }

 }
}

使用上述的代码运行writeLockTest方法并使用writeLock,得出以下结果。

>1
>2
>3
>4
>5
>6
>7
>8
>9
>10
>11
>12
>13
>14
>15
>16
>17
>18
>19
>20

当将testThread.java类中run方法内的writeLockTest行注释掉并取消readLockTest行的注释时,得到了以下结果。

>0time
>0time
>100time
>1000time
>2
>0time
>100time
>1000time
>3
>0time
>100time
>1000time
>4
>100time
>1time
>1001time
>5
>1time
>101time
>101time
>1001time
>6
>1001time
>6
>1time
>1time
>101time
>101time
>1001time
>8
>1001time
>8
>1time
>1time
>101time
>101time
>1001time
>10
>1001time
>10
>1time
>101time
>1001time
>11
>1time
>1time
>101time
>101time
>1001time
>13
>1time
>101time
>1001time
>14
>1001time
>14
>2time
>102time
>1002time
>15
>2time
>2time
>102time
>102time
>1002time
>17
>1002time
>17
>2time
>2time
>102time
>102time
>1002time
>19
>1002time
>19
>2time
>102time
>1002time
>20

根据上述的结果,使用writeLock方法时,直到解除Lock为止,之后的所有代码都不会被执行。然而,使用readLock方法时,即使有下一次访问,两个操作仍会并行进行。但方法内的执行顺序是随机的,我在我的水平上无法理解。虽然不完整,但本文到此为止。

请参阅链接(##)。

以下是Java官方文档的链接:https://docs.oracle.com/javase/8/docs/api/

广告
将在 10 秒后关闭
bannerAds