Re: JavaMemoryModel: Java Class initialization can deadlock?

From: Eric Williams (eric_r_williams@hotmail.com)
Date: Thu Mar 20 2003 - 08:14:46 EST


I actually ran into this problem in a production J2EE application. On
startup, the system would occasionally freeze up and stop processing EJB
requests. Once we dumped the thread stacks, the issue was clearly a class
initialization deadlock.

The classes in question had the following structure:

abstract class Base {
    DerivedA a;
    DerivedB b;
    static {
        a = new DerivedA();
        b = new DerivedB();
    }
}

class DerivedA extends Base { }
class DerivedB extends Base { }

Thread 1:
* new DerivedA();

Thread 2:
* new DerivedB();

Thread 1 grabbed the class initialization lock for DerivedA, then for Base.
Thread 2 grabbed the class initialization lock for DerivedB, and then
blocked on the class initialization lock for Base. Then Thread 1, because
of the static initialization code, tried to grab the class initialization
lock for Derived B, which it then blocked. Deadlock.

We resolved the problem easily. The Base class was acting as a factory for
concrete subtype instances. Instead of using singleton instances of the
concrete types, we switched to lazy reflective instantiation of the concrete
subtype instances in the static factory method.

The advice we took out of it was to limit your inter-class references that
are exercised at class initialization. In general, this meant lazy
initialization for many static variables.

-eric

----- Original Message -----
From: "Bill Pugh" <pugh@cs.umd.edu>
To: <javamemorymodel@cs.umd.edu>; "Gilad Bracha" <gilad.bracha@sun.com>
Sent: Tuesday, March 18, 2003 3:06 PM
Subject: JavaMemoryModel: Java Class initialization can deadlock?

> I believe that according to section 2.17.5 of the JVMS, java class
> initialization can deadlock.
>
> Consider:
>
> class A {
> static int x = 1;
> static {
> B.y = 1;
> }
> }
>
> class B {
> static int y = 2;
> static {
> A.x = 2;
> }
> }
>
> If two separate threads tried to initialize classes A and B and the
> same time, deadlock could occur.
>
> Here is the sequence of events:
>
> T1 executes steps 1 and 6 of 2.17.5 on class A. Class A is now marked
> as InProgress, and unlocked.
>
> T2 executes steps 1 and 6 of 2.17.5 on class B. Class B is now marked
> as InProgress, and unlocked.
>
> T1 executes step 8 of 2.17.5 on class A. This involves an active use of B,
> so T1 tries to initialize B.
>
> T1 executes step 1 on class B. Since B is marked as InProgress, T1 then
> executes step 2, by waiting on B.
>
> T2 executes step 8 of 2.17.5 on class B. This involves an active use of A,
> so T2 tries to initialize B.
>
> T2 executes step 1 on class A. Since A is marked as InProgress, T2 then
> executes step 2, by waiting on A.
>
> Deadlock.
>
> I've been able to get this behavior to occur very consistently by
> putting a two-way barrier in the static initializers for class A and
> B.
>
> Is this something we want to fix?
>
> Note that circular initialization does occur. From the 1.4.2 b18 build:
> IC: Initialization circularity between
> com.sun.jndi.ldap.LdapPoolManager and com.sun.jndi.ldap.pool.Pool
> IC: Initialization circularity between
> sun.awt.datatransfer.DataTransferer and
> sun.awt.datatransfer.DataTransferer$CharsetComparator
> IC: Initialization circularity between
> sun.awt.datatransfer.DataTransferer and
> sun.awt.datatransfer.DataTransferer$DataFlavorComparator
> IC: Initialization circularity between
> sun.awt.datatransfer.DataTransferer$CharsetComparator and
> sun.awt.datatransfer.DataTransferer$DataFlavorComparator
> IC: Initialization circularity between
> sun.nio.cs.ThreadLocalCoders and sun.nio.cs.ThreadLocalCoders$1
> IC: Initialization circularity between
> sun.nio.cs.ThreadLocalCoders and sun.nio.cs.ThreadLocalCoders$2
> IC: Initialization circularity between
> sun.nio.cs.ThreadLocalCoders$1 and sun.nio.cs.ThreadLocalCoders$2
>
>
> -------------------------------
> JavaMemoryModel mailing list -
http://www.cs.umd.edu/~pugh/java/memoryModel
>
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:43 EDT