java - Erratic StampedLock.unlock(long) behaviour? -


i'm facing strange behaviour stampedlock. here main problematic lines of code :

stampedlock lock = new stampedlock(); long stamp1 = lock.readlock(); system.out.printf("read lock count: %d%n", lock.getreadlockcount()); lock.unlock(stamp1 + 2); system.out.printf("read lock count: %d%n", lock.getreadlockcount()); 

the strange behaviour how unlock "tolerates" wrong read stamp. seem correct you?


for reference here full code:

public class stampedlockexample {   static stampedlock lock = new stampedlock();    static void println(string message, object... args) {     system.out.printf(message, args);     system.out.println();   }    static void printreadlockcount() {     println("lock count=%d", lock.getreadlockcount());   }    static long tryreadlock() {     long stamp = lock.tryreadlock();     println("gets read lock (%d)", stamp);     printreadlockcount();     return stamp;   }    static long trywritelock() {     long stamp = lock.trywritelock();     println("gets write lock (%d)", stamp);     return stamp;   }    static long tryconverttoreadlock(long stamp) {     long newone = lock.tryconverttoreadlock(stamp);     println("gets read lock (%d -> %d)", stamp, newone);     printreadlockcount();     return newone;   }    static void tryunlock(long stamp) {     try {       lock.unlock(stamp);       println("unlock (%d) successfully", stamp);     } catch (illegalmonitorstateexception e) {       println("unlock (%d) failed", stamp);     }     printreadlockcount();   }    public static void main(string[] args) {     println("%n--- gets 2 read locks ---");     long stamp1 = tryreadlock();     long stamp2 = tryreadlock();     long min = math.min(stamp1, stamp2);     long max = math.max(stamp1, stamp2);      println("%n--- tries unlock (-1 / +2 / +4) ---");     tryunlock(min - 1);     tryunlock(max + 2);     tryunlock(max + 4);      println("%n--- gets write lock ---");     long stamp3 = trywritelock();      println("%n--- tries unlock (-1 / +1) ---");     tryunlock(stamp3 - 1);     tryunlock(stamp3 + 1);      println("%n--- tries write > read conversion ---");     long stamp4 = tryconverttoreadlock(stamp3);      println("%n--- tries unlock last write stamp (-1 / 0 / +1) ---");     tryunlock(stamp3 - 1);     tryunlock(stamp3);     tryunlock(stamp3 + 1);      println("%n--- tries unlock (-1 / +1) ---");     tryunlock(stamp4 - 1);     tryunlock(stamp4 + 1);   } } 

output:

--- gets 2 read locks --- gets read lock (257) lock count=1 gets read lock (258) lock count=2  --- tries unlock (-1 / +2 / +4) --- unlock (256) failed lock count=2 unlock (260) lock count=1 unlock (262) lock count=0  --- gets write lock --- gets write lock (384)  --- tries unlock (-1 / +1) --- unlock (383) failed lock count=0 unlock (385) failed lock count=0  --- tries write > read conversion --- gets read lock (384 -> 513) lock count=1  --- tries unlock last write stamp (-1 / 0 / +1) --- unlock (383) failed lock count=1 unlock (384) failed lock count=1 unlock (385) failed lock count=1  --- tries unlock (-1 / +1) --- unlock (512) failed lock count=1 unlock (514) lock count=0 

short answer:

adding 2 stamp modifying portion of not require validation in read-mode locks.

long answer:

the stamp contains 2 pieces of information: state sequence number, , how many readers there are. state number stored in first 57 bits of stamp, , reader count stored in last 7 bits. when add 2 stamp, changing reader count 1 3, , leaving state number unchanged. since stampedlock has been acquired in read mode, state number validated , reader count ignored. makes sense because read locks should able unlock in order.

for example: read stamp acquired existing stampedlock , has state number of 4 , reader count of 1. second read stamp acquired same stampedlock , has state number of 4 , reader count of 2. note state numbers of stamps same because stampedlock's state has not changed in between acquisition of stamps. first read stamp used in unlock. state number of first stamp (4) matches state number of stampedlock (4), that's fine. reader count of first stamp (1) not match reader count of stampedlock (2), doesn't matter, because read locks should able unlock in order. unlock succeeds.

note stampedlocks designed high-performing read/write locks internal utilities, not withstand malicious coding, operating within intended boundaries. think javadoc of unlock() misleading though.


Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - Bypass Geo Redirect for specific directories -

php - .htaccess mod_rewrite for dynamic url which has domain names -