JDK-6232022 : Deadlock between system Properties and TimeZone
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2005-02-23
  • Updated: 2011-02-16
  • Resolved: 2005-02-23
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.4.2_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_06-b03)
Java HotSpot(TM) Client VM (build 1.4.2_06-b03, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux ims-dev-101.amazon.com 2.4.21-1asmp #1 SMP Fri Jun 13 15:03:09 PDT 2003 i686 unknown


EXTRA RELEVANT SYSTEM CONFIGURATION :
The example code deadlocks immediately on a multi-CPU box.  In my testing, it wouldn't deadlock on a 1 CPU box.  The same behavior exists for both client and server versions of the VM.

A DESCRIPTION OF THE PROBLEM :
There is a potential deadlock between java.util.TimeZone.getTimeZone(String) and System.getProperties().store(...);




STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
// Compile and run the following code on a multi-CPU machine:
public class TimeZoneDeadlock {
   public static class TimeZoneGetter implements Runnable {
      public void run() {
         while(true) {
            java.util.TimeZone.getTimeZone("GMT");
            try { Thread.sleep(1); } catch(Exception e) {}
         }
      }
   }

   public static class SystemPropertiesStreamer implements Runnable {
      public void run() {
         while(true) {
            java.util.Properties props = System.getProperties();
            try {
               props.store(new java.io.ByteArrayOutputStream(), "");
            } catch(Exception e) {}
            System.out.print(".");
            System.out.flush();
         }
      }
   }

   public static void main(String[] argv) {
      Thread tzGetter =new Thread(new TimeZoneGetter());
      tzGetter.setDaemon(true);
      tzGetter.start();
      Thread spStreamer = new Thread(new SystemPropertiesStreamer());
      spStreamer.start();
   }
}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect the screen to fill with '.'s as the while loop in SystemPropertiesStreamer  runs forever. (This is what happens on a 1-CPU machine)
ACTUAL -
On a box with more than 1 CPU, there is no output, the process hangs.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
kill -3 reveals:
Full thread dump Java HotSpot(TM) Client VM (1.4.2_06-b03 mixed mode):

"DestroyJavaVM" prio=1 tid=0x4c90c3d0 nid=0x6d74 waiting on condition [0..bfffd544]

"Thread-1" prio=1 tid=0x4c90b8e8 nid=0x6d7e waiting for monitor entry [4ce5e000..4ce5e8c8]
        at java.util.TimeZone.getDefault(TimeZone.java:498)
        - waiting to lock <0x48824258> (a java.lang.Class)
        at java.text.SimpleDateFormat.initialize(SimpleDateFormat.java:500)
        at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:443)
        at java.util.Date.toString(Date.java:981)
        at java.util.Properties.store(Properties.java:531)
        - locked <0x44730560> (a java.util.Properties)
        at TimeZoneDeadlock$SystemPropertiesStreamer.run(TimeZoneDeadlock.java:16)
        at java.lang.Thread.run(Thread.java:534)

"Thread-0" daemon prio=1 tid=0x4c90a3e8 nid=0x6d7d waiting for monitor entry [4cddd000..4cddd8c8]
        at java.util.Hashtable.get(Hashtable.java:332)
        - waiting to lock <0x44730560> (a java.util.Properties)
        at java.util.Properties.getProperty(Properties.java:563)
        at java.lang.System.getProperty(System.java:575)
        at sun.security.action.GetPropertyAction.run(GetPropertyAction.java:66)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.util.calendar.ZoneInfoFile.readZoneInfoFile(ZoneInfoFile.java:900)
        at sun.util.calendar.ZoneInfoFile.createZoneInfo(ZoneInfoFile.java:520)
        at sun.util.calendar.ZoneInfoFile.getZoneInfo(ZoneInfoFile.java:499)
        - locked <0x488291d8> (a java.lang.Class)
        at sun.util.calendar.ZoneInfo.getTimeZone(ZoneInfo.java:524)
        at java.util.TimeZone.getTimeZone(TimeZone.java:448)
        at java.util.TimeZone.getTimeZone(TimeZone.java:444)
        - locked <0x48824258> (a java.lang.Class)
        at TimeZoneDeadlock$TimeZoneGetter.run(TimeZoneDeadlock.java:5)
        at java.lang.Thread.run(Thread.java:534)

"Signal Dispatcher" daemon prio=1 tid=0x4c9046d0 nid=0x6d7a waiting on condition [0..0]

"Finalizer" daemon prio=1 tid=0x4c9005f8 nid=0x6d78 in Object.wait() [4ca80000..4ca808c8]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x44730490> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111)
        - locked <0x44730490> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=1 tid=0x08092b38 nid=0x6d77 in Object.wait() [4c8b1000..4c8b18c8]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x44730380> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:429)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:115)
        - locked <0x44730380> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=1 tid=0x0808f9e0 nid=0x6d76 runnable

"VM Periodic Task Thread" prio=1 tid=0x4c906e80 nid=0x6d7c waiting on condition
"Suspend Checker Thread" prio=1 tid=0x4c903d20 nid=0x6d79 runnable

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x08093864 (object 0x48824258, a java.lang.Class),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x0809382c (object 0x44730560, a java.util.Properties),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at java.util.TimeZone.getDefault(TimeZone.java:498)
        - waiting to lock <0x48824258> (a java.lang.Class)
        at java.text.SimpleDateFormat.initialize(SimpleDateFormat.java:500)
        at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:443)
        at java.util.Date.toString(Date.java:981)
        at java.util.Properties.store(Properties.java:531)
        - locked <0x44730560> (a java.util.Properties)
        at TimeZoneDeadlock$SystemPropertiesStreamer.run(TimeZoneDeadlock.java:16)
        at java.lang.Thread.run(Thread.java:534)
"Thread-0":
        at java.util.Hashtable.get(Hashtable.java:332)
        - waiting to lock <0x44730560> (a java.util.Properties)
        at java.util.Properties.getProperty(Properties.java:563)
        at java.lang.System.getProperty(System.java:575)
        at sun.security.action.GetPropertyAction.run(GetPropertyAction.java:66)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.util.calendar.ZoneInfoFile.readZoneInfoFile(ZoneInfoFile.java:900)
        at sun.util.calendar.ZoneInfoFile.createZoneInfo(ZoneInfoFile.java:520)
        at sun.util.calendar.ZoneInfoFile.getZoneInfo(ZoneInfoFile.java:499)
        - locked <0x488291d8> (a java.lang.Class)
        at sun.util.calendar.ZoneInfo.getTimeZone(ZoneInfo.java:524)
        at java.util.TimeZone.getTimeZone(TimeZone.java:448)
        at java.util.TimeZone.getTimeZone(TimeZone.java:444)
        - locked <0x48824258> (a java.lang.Class)
        at TimeZoneDeadlock$TimeZoneGetter.run(TimeZoneDeadlock.java:5)
        at java.lang.Thread.run(Thread.java:534)

Found 1 deadlock.


REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------
// Compile and run the following code on a multi-CPU machine:
public class TimeZoneDeadlock {
   public static class TimeZoneGetter implements Runnable {
      public void run() {
         while(true) {
            java.util.TimeZone.getTimeZone("GMT");
            try { Thread.sleep(1); } catch(Exception e) {}
         }
      }
   }

   public static class SystemPropertiesStreamer implements Runnable {
      public void run() {
         while(true) {
            java.util.Properties props = System.getProperties();
            try {
               props.store(new java.io.ByteArrayOutputStream(), "");
            } catch(Exception e) {}
            System.out.print(".");
            System.out.flush();
         }
      }
   }

   public static void main(String[] argv) {
      Thread tzGetter =new Thread(new TimeZoneGetter());
      tzGetter.setDaemon(true);
      tzGetter.start();
      Thread spStreamer = new Thread(new SystemPropertiesStreamer());
      spStreamer.start();
   }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
1) Synchronize on TimeZone.class before calling store(...) on the system Properties object.
2) Make a copy of the system properties object and call store(...) on the copy rather than the real system properties object.
###@###.### 2005-2-23 06:00:09 GMT

Comments
EVALUATION dup of 6199320 ###@###.### 2005-2-23 06:28:34 GMT
23-02-2005