code: package freed.image;
  
  import java.util.concurrent.BlockingQueue;
  import java.util.concurrent.LinkedBlockingDeque;
  import java.util.concurrent.RejectedExecutionHandler;
  import java.util.concurrent.ThreadPoolExecutor;
  import java.util.concurrent.TimeUnit;
  
  import freed.utils.Log;
  
  public class ThreadPoolQueue {
      private final int KEEP_ALIVE_TIME = 500;
      private BlockingQueue<Runnable> executerQueue;
      private ThreadPoolExecutor executer;
  
  
      public void create(int coreSize, int queueSize)
      {
          if (queueSize > 0)
              executerQueue = new LinkedBlockingDeque<>(queueSize);
          else
              executerQueue = new LinkedBlockingDeque<>();
          executer = new ThreadPoolExecutor(
                  coreSize,       // Initial pool size
                  coreSize,       // Max pool size
                  KEEP_ALIVE_TIME,
                  TimeUnit.MILLISECONDS,
                  executerQueue);
      }
  
      public void create()
      {
          int coreSize = Runtime.getRuntime().availableProcessors();
          create(coreSize,0);
      }
  
      public void create(RejectedExecutionHandler rejectedExecutionHandler)
      {
          create();
          executer.setRejectedExecutionHandler(rejectedExecutionHandler);
      }
  
      public void create(int coreSize,RejectedExecutionHandler rejectedExecutionHandler)
      {
          create(coreSize,coreSize);
          executer.setRejectedExecutionHandler(rejectedExecutionHandler);
      }
  
      public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler)
      {
          executer.setRejectedExecutionHandler(rejectedExecutionHandler);
      }
  
      public RejectedExecutionHandler getRejectedExecutionHandler()
      {
          return executer.getRejectedExecutionHandler();
      }
  
      public void cancel()
      {
          ImageTask[] tasks = new ImageTask[executerQueue.size()];
          executerQueue.toArray(tasks);
          for (ImageTask task : tasks)
          {
              Thread thread = task.getThread();
              if (thread != null)
                  thread.interrupt();
          }
          executerQueue.clear();
      }
  
      public void removeTaskFromQueue(ImageTask task)
      {
          boolean removed = executerQueue.remove(task);
          Log.d("ThreadPoolQueue", "Removed task:");
          try {
              if (task != null && task.getThread() != null && !task.getThread().isInterrupted())
                  task.getThread().interrupt();
          }
          catch (NullPointerException ex)
          {
              Log.WriteEx(ex);
          }
      }
  
      public void addTask(ImageTask task)
      {
          executer.execute(task);
      }
  
      public int remainingCapacity() {
          return executerQueue.remainingCapacity();
      }
  }
  