multithreading - Java Synchronization Not Working as Expected -


i have "simple" 4 class example reliably shows unexpected behavior java synchronization on multiple machines. can read below, given contract of java sychronized keyword, broke synchronization should never printed class testbuffer.

here 4 classes reproduce issue (at least me). i'm not interested in how fix broken example, rather why breaks in first place.

sync issue - controller.java

sync issue - synctest.java

sync issue - testbuffer.java

sync issue - tuple3f.java

and here output when run it:

java -cp . synctest before adding creating testbuffer before remove broke synchronization 1365192 broke synchronization 1365193 broke synchronization 1365194 broke synchronization 1365195 broke synchronization 1365196 done 

update: @gray has simplest example breaks far. example can found here: strange jrc race condition

based on feedback i've gotten others, looks issue may occur on java 64-bit 1.6.0_20-1.6.0_31 (unsure newer 1.6.0's) on windows , osx. nobody has been able reproduce issue on java 7. may require multi-core machine reproduce issue.

original question:

i have class provides following methods:

  • remove - removes given item list
  • getbuffer - iterates on items in list

i've reduced problem down 2 functions below, both of in same object , they're both synchronized. unless mistaken, "broke synchronization" should never printed because insidegetbuffer should set false before remove can entered. however, in application printing "broke synchronization" when have 1 thread calling remove repeatedly while other calls getbuffer repeatedly. symptom concurrentmodificationexception.

see also:

very strange race condition looks jre issue

sun bug report:

this confirmed bug in java sun. apparently fixed (unknowingly?) in jdk7u4, have not backported fix jdk6. bug id: 7176993

i think indeed looking @ jvm bug in osr. using simplified program @gray (slight modifications print error message) , options mess with/print jit compilation, can see going on jit. and, can use options control degree can suppress issue, lends lot of evidence being jvm bug.

running as:

java -xx:+printcompilation -xx:compilethreshold=10000 phil.strangeraceconditiontest 

you can error condition (like others 80% of runs) , compilation print like:

 68   1       java.lang.string::hashcode (64 bytes)  97   2       sun.nio.cs.utf_8$decoder::decodearrayloop (553 bytes) 104   3       java.math.biginteger::muladd (81 bytes) 106   4       java.math.biginteger::multiplytolen (219 bytes) 111   5       java.math.biginteger::addone (77 bytes) 113   6       java.math.biginteger::squaretolen (172 bytes) 114   7       java.math.biginteger::primitiveleftshift (79 bytes) 116   1%      java.math.biginteger::multiplytolen @ 138 (219 bytes) 121   8       java.math.biginteger::montreduce (99 bytes) 126   9       sun.security.provider.sha::implcompress (491 bytes) 138  10       java.lang.string::charat (33 bytes) 139  11       java.util.arraylist::ensurecapacity (58 bytes) 139  12       java.util.arraylist::add (29 bytes) 139   2%      phil.strangeraceconditiontest$buffer::<init> @ 38 (62 bytes) 158  13       java.util.hashmap::indexfor (6 bytes) 159  14       java.util.hashmap::hash (23 bytes) 159  15       java.util.hashmap::get (79 bytes) 159  16       java.lang.integer::valueof (32 bytes) 168  17 s     phil.strangeraceconditiontest::getbuffer (66 bytes) 168  18 s     phil.strangeraceconditiontest::remove (10 bytes) 171  19 s     phil.strangeraceconditiontest$buffer::remove (34 bytes) 172   3%      phil.strangeraceconditiontest::strangeraceconditiontest @ 36 (76 bytes) errors //my little change 219  15      made not entrant  java.util.hashmap::get (79 bytes) 

there 3 osr replacements (the ones % annotation on compile id). guess is third one, loop calling remove(), responsible error. can excluded jit via .hotspot_compiler file located in working directory following contents:

exclude phil/strangeraceconditiontest strangeraceconditiontest 

when run program again, output:

compileroracle: exclude phil/strangeraceconditiontest.strangeraceconditiontest  73   1       java.lang.string::hashcode (64 bytes) 104   2       sun.nio.cs.utf_8$decoder::decodearrayloop (553 bytes) 110   3       java.math.biginteger::muladd (81 bytes) 113   4       java.math.biginteger::multiplytolen (219 bytes) 118   5       java.math.biginteger::addone (77 bytes) 120   6       java.math.biginteger::squaretolen (172 bytes) 121   7       java.math.biginteger::primitiveleftshift (79 bytes) 123   1%      java.math.biginteger::multiplytolen @ 138 (219 bytes) 128   8       java.math.biginteger::montreduce (99 bytes) 133   9       sun.security.provider.sha::implcompress (491 bytes) 145  10       java.lang.string::charat (33 bytes) 145  11       java.util.arraylist::ensurecapacity (58 bytes) 146  12       java.util.arraylist::add (29 bytes) 146   2%      phil.strangeraceconditiontest$buffer::<init> @ 38 (62 bytes) 165  13       java.util.hashmap::indexfor (6 bytes) 165  14       java.util.hashmap::hash (23 bytes) 165  15       java.util.hashmap::get (79 bytes) 166  16       java.lang.integer::valueof (32 bytes) 174  17 s     phil.strangeraceconditiontest::getbuffer (66 bytes) 174  18 s     phil.strangeraceconditiontest::remove (10 bytes) ### excluding compile: phil.strangeraceconditiontest::strangeraceconditiontest 177  19 s     phil.strangeraceconditiontest$buffer::remove (34 bytes) 324  15      made not entrant  java.util.hashmap::get (79 bytes) 

and problem not appear (at least not in repeated attempts i've made).

also, if change jvm options bit, can cause problem go away. using either of following cannot problem appear.

java -xx:+printcompilation -xx:compilethreshold=100000 phil.strangeraceconditiontest java -xx:+printcompilation -xx:freqinlinesize=1 phil.strangeraceconditiontest 

interestingly, compilation output both of these still show osr remove loop. guess (and big one) delaying jit via compilation threshold or changing freqinlinesize cause changes osr processing in these cases bypass bug otherwise hitting.

see here info on jvm options.

see here , here information on output of -xx:+printcompilation , how mess jit does.


Comments

Popular posts from this blog

django - How can I change user group without delete record -

java - Need to add SOAP security token -

java - EclipseLink JPA Object is not a known entity type -