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

com.stanfy.enroscar.goro.Queues Maven / Gradle / Ivy

There is a newer version: 3.0.0-RC5
Show newest version
package com.stanfy.enroscar.goro;

import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Build;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Internal queues.
 */
interface Queues {

  /**
   * Set main executor used to really perform tasks.
   * @param mainExecutor executor that tasks are delegated to
   */
  void setDelegateExecutor(Executor mainExecutor);

  /**
   * @param queueName queue name
   * @return executor that performs all the tasks in a given queue
   */
  Executor getExecutor(String queueName);

  /**
   * Remove tasks from a queue.
   * @param queueName queue name
   */
  void clear(String queueName);

  /** Default implementation. */
  class Impl implements Queues {

    /** Thread pool parameter. */
    private static final int CORE_POOL_SIZE = 5,
        MAXIMUM_POOL_SIZE = 32,
        KEEP_ALIVE = 7,
        MAX_QUEUE_LENGTH = 100;

    /** Default threads pool. */
    private static Executor defaultThreadPoolExecutor;

    /** Executors map. */
    private final HashMap executorsMap = new HashMap<>();

    /** Used threads pool. */
    private Executor delegateExecutor;

    private static Executor getDefaultThreadPoolExecutor() {
      if (defaultThreadPoolExecutor == null) {
        Executor executor = getAsyncTaskThreadPool();
        if (executor == null) {
          final AtomicInteger threadCounter = new AtomicInteger();
          //noinspection NullableProblems
          ThreadFactory tFactory = new ThreadFactory() {
            @Override
            public Thread newThread(final Runnable r) {
              return new Thread(r, "Goro Thread #" + threadCounter.incrementAndGet());
            }
          };
          final LinkedBlockingQueue queue = new LinkedBlockingQueue<>(MAX_QUEUE_LENGTH);
          executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE,
              KEEP_ALIVE, TimeUnit.SECONDS, queue, tFactory);
        }
        defaultThreadPoolExecutor = executor;
      }
      return defaultThreadPoolExecutor;
    }

    @SuppressLint("NewApi")
    private static Executor getAsyncTaskThreadPool() {
      return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
          ? AsyncTask.THREAD_POOL_EXECUTOR
          : null;
    }

    @Override
    public void setDelegateExecutor(final Executor mainExecutor) {
      if (mainExecutor == null) {
        throw new IllegalArgumentException("Null threads pool");
      }
      synchronized (executorsMap) {
        if (!executorsMap.isEmpty()) {
          throw new IllegalStateException("Delegate executor cannot be changed after any queue is created");
        }
        this.delegateExecutor = mainExecutor;
      }
    }

    @Override
    public Executor getExecutor(final String queueName) {
      synchronized (executorsMap) {
        if (delegateExecutor == null) {
          delegateExecutor = getDefaultThreadPoolExecutor();
        }

        if (queueName == null) {
          return delegateExecutor;
        }

        TaskQueueExecutor exec = executorsMap.get(queueName);
        if (exec == null) {
          exec = new TaskQueueExecutor(delegateExecutor);
          executorsMap.put(queueName, exec);
        }
        return exec;
      }
    }

    @Override
    public void clear(final String queueName) {
      final TaskQueueExecutor exec;
      synchronized (executorsMap) {
        exec = executorsMap.get(queueName);
      }
      if (exec != null) {
        exec.clear();
      }
    }
  }

  /** Executor for the task queue. */
  final class TaskQueueExecutor implements Executor {
    /** Delegate executor. */
    final Executor delegate;
    /** Tasks queue. */
    final LinkedList tasks = new LinkedList<>();
    /** Active task. */
    Runnable activeTask;

    public TaskQueueExecutor(final Executor delegate)  {
      this.delegate = delegate;
    }

    @SuppressWarnings("NullableProblems")
    @Override
    public synchronized void execute(final Runnable r) {
      tasks.offer(new Runnable() {
        @Override
        public void run() {
          try {
            r.run();
          } finally {
            scheduleNext();
          }
        }
      });
      if (activeTask == null) {
        scheduleNext();
      }
    }

    synchronized void scheduleNext() {
      activeTask = tasks.poll();
      if (activeTask != null) {
        delegate.execute(activeTask);
      }
    }

    synchronized void clear() {
      tasks.clear();
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy