All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intellij.concurrency.JobScheduler Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition core-api library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * @author max
 */
package com.intellij.concurrency;

import com.intellij.Patches;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.ReflectionUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;


import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;

public abstract class JobScheduler {
  private static final ScheduledThreadPoolExecutor ourScheduledExecutorService;
  private static final int TASK_LIMIT = 50;
  private static final Logger LOG = Logger.getInstance("#com.intellij.concurrency.JobScheduler");
  private static final ThreadLocal START = new ThreadLocal();
  private static final boolean DO_TIMING = true;

  static {
    ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, ConcurrencyUtil.newNamedThreadFactory("Periodic tasks thread", true, Thread.NORM_PRIORITY)) {
      @Override
      protected void beforeExecute(Thread t, Runnable r) {
        if (DO_TIMING) {
          START.set(System.currentTimeMillis());
        }
      }

      @Override
      protected void afterExecute(Runnable r, Throwable t) {
        if (DO_TIMING) {
          long elapsed = System.currentTimeMillis() - START.get();
          Object unwrapped;
          if (elapsed > TASK_LIMIT && (unwrapped = info(r)) != null) {
            @NonNls String msg = TASK_LIMIT + " ms execution limit failed for: " + unwrapped + "; elapsed time was " + elapsed +"ms";
            LOG.info(msg);
          }
        }
      }
    };
    executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
    executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
    enableRemoveOnCancelPolicy(executor);
    ourScheduledExecutorService = executor;
  }

  private static Object info(Runnable r) {
    if (!(r instanceof FutureTask)) return r;
    Object sync = ReflectionUtil.getField(FutureTask.class, r, null, "sync"); // FutureTask.sync in <=JDK7
    Object o = sync == null ? r : sync;
    Object callable = ReflectionUtil.getField(o.getClass(), o, Callable.class, "callable"); // FutureTask.callable or Sync.callable
    if (callable == null) return null;
    Object task = ReflectionUtil.getField(callable.getClass(), callable, null, "task"); // java.util.concurrent.Executors.RunnableAdapter.task
    return task == null ? callable : task;
  }

  private static void enableRemoveOnCancelPolicy(ScheduledThreadPoolExecutor executor) {
    if (Patches.USE_REFLECTION_TO_ACCESS_JDK7) {
      try {
        Method setRemoveOnCancelPolicy = ReflectionUtil.getDeclaredMethod(ScheduledThreadPoolExecutor.class, "setRemoveOnCancelPolicy", boolean.class);
        setRemoveOnCancelPolicy.invoke(executor, true);
      }
      catch (Exception ignored) {
      }
    }
  }

  public static JobScheduler getInstance() {
    return ServiceManager.getService(JobScheduler.class);
  }

  @NotNull
  public static ScheduledExecutorService getScheduler() {
    return ourScheduledExecutorService;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy