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

java.util.concurrent.ScheduledThreadPoolExecutor hangs.

XMLWordPrintable

      FULL PRODUCT VERSION :
      On windows:
      java version "1.8.0_25"
      Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
      Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

      On Linux:
      Java(TM) SE Runtime Environment (build 1.7.0_71-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [verziószám: 6.1.7601]

      Linux seres 3.17.4-200.fc20.x86_64 #1 SMP Fri Nov 21 23:26:41 UTC 2014
      x86_64 x86_64 x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      Java Executor Service hangs while shceduling a lot of runnable object with Long.MAX_VALUE timeout parameter.
      If the TimeOut parameter is set to Long.MAX_VALUE then in 1 minute or so the java executor service hangs.

      REGRESSION. Last worked in version 7u71

      ADDITIONAL REGRESSION INFORMATION:
      On windows:
      java version "1.8.0_25"
      Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
      Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

      On Linux:
      Java(TM) SE Runtime Environment (build 1.7.0_71-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Please see the attached source code.


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      /*
       * Java Executor Service hangs while shceduling a lot of runnable object with Long.MAX_VALUE timeout parameter.
       * If the TimeOut parameter is set to Long.MAX_VALUE then in 1 minute or so the java executor service hangs.
       * This fault was found by my boss Kristof Nagy (nagykr@gmail.com) while he was testing our ElasticSearch based project
       */
      package oraclejavaerror;

      import java.text.DecimalFormat;
      import java.text.DecimalFormatSymbols;
      import java.text.NumberFormat;
      import java.util.Locale;
      import java.util.Map;
      import java.util.concurrent.ConcurrentHashMap;
      import java.util.concurrent.ScheduledFuture;
      import java.util.concurrent.ScheduledThreadPoolExecutor;
      import java.util.concurrent.TimeUnit;
      import java.util.concurrent.atomic.AtomicInteger;
      import java.util.concurrent.atomic.AtomicLong;

      /**
       * @author Kalman Kovacs - kalman.kovacs@gmail.com
       */
      public class OracleJavaError {

      private final static long WrongValue = Long.MAX_VALUE;
      private final static long GoodValue = Long.MAX_VALUE >> 24;
      private final static long TimeOut = WrongValue;

      private final static int ServiceStarterParallelRunning = 16;
      private final static long MaxCollectionSize = 1_000_000L;
      private final static AtomicLong counter = new AtomicLong(0);
      private final static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(256);
      private final static Map<Long, ScheduledFuture<?>> futures = new ConcurrentHashMap<>();

      public static void main(String[] args) throws InterruptedException {
      executor.setRemoveOnCancelPolicy(true);

      // Controll Service
      final AtomicInteger controlServiceTime = new AtomicInteger(1000);
      final int maxControlServiceTime = 5000;
      executor.schedule(new Runnable() {

      @Override
      public void run() {
      if (controlServiceTime.get() < maxControlServiceTime) {
      controlServiceTime.addAndGet(100);
      }
      System.out.println("Number of started Threads: " + formatter(counter.get())
      + " (Collection size: " + formatter(futures.size())
      + ", Next running time: " + controlServiceTime.get() + " ms)");
      executor.schedule(this, controlServiceTime.get(), TimeUnit.MILLISECONDS);
      }
      }, controlServiceTime.get(), TimeUnit.MILLISECONDS);


      // Service Starter + Service
      for (int i = 0; i < ServiceStarterParallelRunning; i++) {
      executor.schedule(new Runnable() {

      @Override
      public void run() { //Service Starter
      ScheduledFuture<?> future = executor.schedule(new Runnable() {

      @Override
      public void run() { //Service - IT IS NEVER RUNNING! (because the TimeOut is too big).
      System.out.println("A srvices is running..");
      }
      }, TimeOut, TimeUnit.MILLISECONDS);
      long uniqueId = counter.incrementAndGet();
      futures.put(uniqueId, future);
      if (uniqueId > MaxCollectionSize) {
      futures.remove(uniqueId - MaxCollectionSize).cancel(true);
      }
      executor.submit(this);
      }
      }, 1000, TimeUnit.MILLISECONDS);
      }
      Thread.currentThread().sleep(86_400_000);
      }

      private static String formatter(long value) {
      DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);
      DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols();
      symbols.setGroupingSeparator(' ');
      return formatter.format(value);
      }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      If the TimeOut parameter is set less than or equal (Long.MAX_VALUE >> 24), while the TimeUnit is set to MILLISECONDS.


      SUPPORT :
      YES

            vklang Viktor Klang
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: