Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7145454

JVM wide monitor lock in Currency.getInstance(String)

XMLWordPrintable

    • b32
    • x86
    • linux

        FULL PRODUCT VERSION :
        java version "1.7.0_01"
        Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
        Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)


        ADDITIONAL OS VERSION INFORMATION :
        Linux 2.6.18-274.3.1.e15 x86_64

        EXTRA RELEVANT SYSTEM CONFIGURATION :
        multi-threaded (~50 thead) process with high throughput

        A DESCRIPTION OF THE PROBLEM :
        When you call String.format("%s.%s", s1, s2), where s1 and s2 are any string, this ends up entering a synchronized block on a static object (instances) in java.util.Currency and can block all threads in the system doing the same thing. This somewhat antisocial thread policy is not documented.



        REGRESSION. Last worked in version 6u29

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Just set up lots of threads doing a String.format() and watch it using jvisualvm on the Threads tab

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        I do not expect String.format() to ever need to block, as there is no indication that there is any requirement for it to have any state.
        ACTUAL -
        JVM-wide monitor locks,severely limiting throughput.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        package bnpp.xiphias.lvc;

        import java.util.concurrent.Executors;
        import java.util.concurrent.ScheduledExecutorService;

        public class Locker {
        public static void main(String... args) {
        Locker locker = new Locker();
        locker.execute();
        }

        private void execute() {
        final ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);

        executor.execute(new Runnable() {
        public void run() {
        while (true) {
        executor.submit(newTask());
        }
        }
        });

        try {
        Thread.sleep(120000);
        } catch(InterruptedException ie) {

        } finally {
        executor.shutdown();
        }

        }

        private Runnable newTask() {
        return new Runnable() {
        @Override
        public void run() {
        String.format("%s.%s", "a", "b");
        }
        };
        }
        }

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

        CUSTOMER SUBMITTED WORKAROUND :
        Do not use String.format(), which is not exactly an easy thing to achieve with a vast existing code-base

              naoto Naoto Sato
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: