java - Why does parallel stream with lambda in static initializer cause a deadlock? -


i came across strange situation using parallel stream lambda in static initializer takes seemingly forever no cpu utilization. here's code:

class deadlock {     static {         intstream.range(0, 10000).parallel().map(i -> i).count();         system.out.println("done");     }     public static void main(final string[] args) {} } 

this appears minimum reproducing test case behavior. if i:

  • put block in main method instead of static initializer,
  • remove parallelization, or
  • remove lambda,

the code instantly completes. can explain behavior? bug or intended?

i using openjdk version 1.8.0_66-internal.

i found bug report of similar case (jdk-8143380) closed "not issue" stuart marks:

this class initialization deadlock. test program's main thread executes class static initializer, sets initialization in-progress flag class; flag remains set until static initializer completes. static initializer executes parallel stream, causes lambda expressions evaluated in other threads. threads block waiting class complete initialization. however, main thread blocked waiting parallel tasks complete, resulting in deadlock.

the test program should changed move parallel stream logic outside of class static initializer. closing not issue.


i able find bug report of (jdk-8136753), closed "not issue" stuart marks:

this deadlock occurring because fruit enum's static initializer interacting badly class initialization.

see java language specification, section 12.4.2 details on class initialization.

http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.2

briefly, what's happening follows.

  1. the main thread references fruit class , starts initialization process. sets initialization in-progress flag , runs static initializer on main thread.
  2. the static initializer runs code in thread , waits finish. example uses parallel streams, has nothing streams per se. executing code in thread means, , waiting code finish, have same effect.
  3. the code in other thread references fruit class, checks initialization in-progress flag. causes other thread block until flag cleared. (see step 2 of jls 12.4.2.)
  4. the main thread blocked waiting other thread terminate, static initializer never completes. since initialization in-progress flag isn't cleared until after static initializer completes, threads deadlocked.

to avoid problem, make sure class's static initialization completes quickly, without causing other threads execute code requires class have completed initialization.

closing not issue.


note findbugs has open issue adding warning situation.


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

css - Make div keyboard-scrollable in jQuery Mobile? -

ruby on rails - Seeing duplicate requests handled with Unicorn -