Strange behavior of StampedLock with Thread class

泄露秘密 提交于 2021-01-28 18:16:13

问题


I'm running this code in IntellijIDEA Community on Windows

import static java.lang.Thread.sleep;

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

        StampedLock lock = new StampedLock();
        Thread th = new Thread(() -> {
            long stamp = lock.tryOptimisticRead();
            try {
                System.out.println("Optimistic Lock Valid: " + lock.validate(stamp));
                sleep(1);
                System.out.println("Optimistic Lock Valid: " + lock.validate(stamp));
                sleep(2);
                System.out.println("Optimistic Lock Valid: " + lock.validate(stamp));
            } catch (InterruptedException ex) {
            } finally {
                lock.unlock(stamp);
            }
        });

        th.start();
        try {
            th.join();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}

and I'm getting the valid output, but with the IllegalMonitorStateException

"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:C:\Users\izotova\IntelliJ IDEA Community Edition 2019.3.3\lib\idea_rt.jar=54575:C:\Users\izotova\IntelliJ IDEA Community Edition 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;C:\Users\izotova\Documents\case-study-java-backend\Tasks\out\production\tasks" Main
Optimistic Lock Valid: true
Optimistic Lock Valid: true
Optimistic Lock Valid: true
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.StampedLock.unlock(StampedLock.java:609)
    at Main.lambda$main$0(Main.java:22)
    at java.lang.Thread.run(Thread.java:748)

Process finished with exit code 0

I honestly have no ideas, what could cause this, the stamp and lock are fine, no idea, what I'm doing incorrectly. Maybe you have some ideas or insights about how stamped locks work internally?


回答1:


I'm going to double down on the guess in my comment above and say that I don't think that optimistic locks can be unlocked (or need to be).

Here is an example pulled straight from the documentation of StampedLock. Notice that in the unlock portion of the code they are careful to call unlock() only if the stamp has been upgraded from an optimistic lock to a read lock. The example does NOT try to unlock if the lock is still an optimistic lock.

   // a read-only method
   // upgrade from optimistic read to read lock
   double distanceFromOrigin() {
     long stamp = sl.tryOptimisticRead();
     try {
       retryHoldingLock: for (;; stamp = sl.readLock()) {
         if (stamp == 0L)
           continue retryHoldingLock;
         // possibly racy reads
         double currentX = x;
         double currentY = y;
         if (!sl.validate(stamp))
           continue retryHoldingLock;
         return Math.hypot(currentX, currentY);
       }
     } finally {
       if (StampedLock.isReadLockStamp(stamp))
         sl.unlockRead(stamp);
     }
   }


来源:https://stackoverflow.com/questions/60821239/strange-behavior-of-stampedlock-with-thread-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!