title: Class used (in one thread) before being fully initialized (by another)?
body: <p>Deep inside a library I'm using, there are two mutually referential classes &mdash; call them <code>MR1</code> and <code>MR2</code> &mdash; such that <code>MR1.&lt;clinit&gt;</code> causes <code>MR2</code> to be classloaded and <code>MR2.&lt;clinit&gt;</code> causes <code>MR1</code> to be classloaded.</p>
  
  <p>The library also has a <code>Util</code> class that refers to <code>MR1</code>, such that <code>Util.&lt;clinit&gt;</code> causes <code>MR1</code> to be classloaded.</p>
  
  <p>Lastly, it has a top-level class &mdash; call it <code>TopLevel</code> &mdash; whose constructor has some code like this:</p>
  
  <pre><code>Util.callStaticUtilMethod();
  MR2.callStaticMR2Method();
  </code></pre>
  
  <p>So the overall dependency graph is something like this:</p>
  
  <p><a href="https://i.stack.imgur.com/bjQuY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bjQuY.png" alt="dependency graph"></a></p>
  
  <p>I recently encountered a classloader deadlock where two threads both happened to be instantiating <code>TopLevel</code> at the same time, with none of these other classes having been loaded yet. One thread got stuck in <code>MR1.&lt;clinit&gt;</code>, inside <code>Util.&lt;clinit&gt;</code>, in preparation for calling <code>Util.callStaticUtilMethod()</code>; the other successfully got past <code>Util.callStaticUtilMethod()</code>, and got stuck in <code>MR2.&lt;clinit&gt;</code>, in preparation for calling <code>MR2.callStaticMR2Method()</code>. (And then a bunch of other threads got stuck on the <code>MR2.callStaticMR2Method()</code> line.)</p>
  
  <p>What I don't understand is &mdash; if one thread is still stuck, deadlocked, inside <code>Util.&lt;clinit&gt;</code>, then how come all the other threads were able to get past the <code>Util.callStaticUtilMethod()</code> call? Is it supposed to be possible for a class to be used before it's completely initialized? If so, then how far does this go; for example, could a static final field be accessed by one thread before it's been initialized by another? (From the fact that the other threads weren't able to get past the <code>MR2.callStaticMR2Method()</code> call, it seems that this <em>isn't</em> a total free-for-all, fortunately; but I can't tell what the rules might be.)</p>