multithreading - In Java, multiple threads want to manipulate one object, how to get one manipulate that and the others wait until the work is done? -


my problem little complicated: have concurrent map, threads want visit , update map, if 2 thread want fetch same entry of map, 1 should first map, update it, , other should wait until entry has been updated , fetch entry. original thought that: can use concurrent map, same key targeting map , use latch value. code like:

private final concurrentmap<long, list<rowkeymap>> targetmap;     private final concurrentmap<long, countdownlatch> helpermap;    long keymillis; //key   countdownlatch restorelatch = helpermap.get(keymillis);      if (restorelatch != null) {       try {         restorelatch.await();       } catch (interruptedexception e) {         thread.currentthread().interrupt();         throw new runtimeexception("interrupted trying " + keymillis);       }     }      list<rowkeymap> restoredata = targetmap.get(keymillis);      if (restoredata == null) {       //find entry should restored, put latch helpermap , restore        restorelatch = new countdownlatch(1);       countdownlatch existinglatch = helpermap.putifabsent(keymillis, restorelatch);        if (existinglatch == null) {         microshards = new arraylist<>(count);          (int = 0; < count; ++i) {             microshards.add(new rowkeymap(some parameters));         }         list<rowkeymap> existing = targetmap.putifabsent(keymillis, microshards);          if (existing == null) {            {do actual restore job here}         } else {            microshards = existing;         }         restorelatch.countdown();         restoresbydate.remove(keymillis);       } else {         // lost race, wait restore task complete , new restoredata         try {           existinglatch.await();         } catch (interruptedexception e) {           thread.currentthread().interrupt();           throw new runtimeexception("interrupted trying " + keymillis);         }         {get new restoredata}       }     } 

but current version has bug:

  • thread executes through first line, gets null restorelatch
  • thread b wakes , executes through first line, gets null restorelatch
  • thread b continues on following lines, sees existinglatch null
  • thread b continues, puts created-but-not-yet-restored-into list restoredata
  • thread wakes , executes through, created-but-not-yet-restored-into list restoredata

anyone has ideas solve this? thanks!

so want lock per each map entry. i'm not sure countdownlatch ideal here, because cannot re-used, , creating new 1 each time complicates problem.

but basic problem not preventing race condition lock itself.

in order that, must first ensure lock object entry exists, , if 2 threads go same entry, they same lock.

you can first creating lock object, use putifabsent put in lock map:

object entrylock = new object(); object returnedlock = helpermap.putifabsent( keymillis, entrylock ); entrylock = returnedlock == null ? entrylock : returnedlock; 

what ensure 2 threads trying access same entry (keymillis) same lock instance. if thread first run putifabsent line, new object created in first line going 1 placed in helper map, , it's going null back, means use object placed in map - entrylock. thread b comes along , create own entrylock. when tries putifabsent line, there object mapped keymillis, returnedlock, , that's object use (in case, original new lock created discarded garbage collection).

so whichever order thy putifabsent line, using same lock instance. next step is:

  • lock lock.
  • run processing of data in targetmap, creating if doesn't exist, updating if does, etc. time, other threads particular keymillis waiting, threads other keymillis don't.
  • unlock lock. 1 of other threads wait keymillis entry lock lock.

to pretty simple:

synchronized(entrylock) {    // operations on particular entry } 

if need fancier lock facilities use reentrantlock or cyclicbarrier. countdownlatch need replaced new 1 usable, , defeat arrangement above, pretty relies on lock object being same threads.


Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -