package org.googlecode.threadpool; import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.RejectedExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** {@link Policy} */ public enum Policy { /** 乐观策略, 在存在为分配的配额情况下, 一旦出现闲置线程, 允许任务抢占, 抢占的优先级由提交的先后顺序决定. */ OPTIMISM { /** 未定义配额的任务将直接进入等待队列, 但优先级低于所有定义了配额的任务. */ public final Submitter defaultSubmitter = new Submitter() { @Override public void submit(Runnable task, CentralExecutor executor) { enqueue(new ComparableTask(task, Integer.MAX_VALUE)); } }; @Override public Submitter defaultSubmitter() { return defaultSubmitter; } @Override public Submitter submitter(final Quota reserve, final Quota elastic) { return new Submitter() { @Override public void submit(final Runnable task, CentralExecutor executor) { if (reserve.acquire()) doSubmit(task, executor, reserve); // 若存在为分配的预留配额, 则弹性配额进行争抢 else if (executor.hasUnreserved() && elastic.acquire()) doSubmit(task, executor, elastic); // 同悲观策略进入等待队列 else enqueue(new ComparableTask(task, reserve.getValue())); } }; } }, /** 悲观策略, 在所有线程都被预留的情况下, 即使当前预留之外的线程是空闲, 也不会被抢占, 即Elastic的设定将被忽略. */ PESSIMISM { public final Submitter defaultSubmitter = new Submitter() { @Override public void submit(Runnable task, CentralExecutor executor) { throw new RejectedExecutionException( "Unquotaed task can not be executed in pessimism."); } }; @Override public Submitter defaultSubmitter() { return defaultSubmitter; } @Override public Submitter submitter(final Quota reserve, final Quota elastic) { if (reserve.getValue() == 0) throw new IllegalArgumentException( "None-reserve task will never be executed in pessimism."); return new Submitter() { @Override public void submit(final Runnable task, CentralExecutor executor) { if (reserve.acquire()) doSubmit(task, executor, reserve); // 耗尽预留配额后, 进入等待队列, 按预留额度大小排优先级, 大者优先. else enqueue(new ComparableTask(task, reserve.getValue())); } }; } }; /** 优先级等待队列. */ private final PriorityBlockingQueue<ComparableTask> queue = new PriorityBlockingQueue<ComparableTask>(); public abstract Submitter submitter(Quota reserve, Quota elastic); public abstract Submitter defaultSubmitter(); private static final Logger LOGGER = LoggerFactory .getLogger(CentralExecutor.class); /** 将任务入等待队列. */ void enqueue(ComparableTask task) { queue.put(task); LOGGER.debug("Enqueue {}", task.original); } /** 将任务出列重新提交给执行器. */ void dequeueTo(CentralExecutor executor) { try { final Runnable task = queue.take().original; LOGGER.debug("Dequeue {}", task); executor.execute(task); } catch (InterruptedException e) { Thread.currentThread().interrupt(); LOGGER.debug("Dequeue has been interrupted ", e); } } void doSubmit(Runnable task, CentralExecutor executor, Quota quota) { executor.service.execute(new Decorator(task, quota, executor)); } /** {@link ComparableTask} */ static class ComparableTask implements Comparable<ComparableTask> { final Runnable original; private final int quota; public ComparableTask(Runnable task, int quota) { this.original = task; this.quota = quota; } @Override public int compareTo(ComparableTask o) { return -(quota - o.quota); } } /** {@link Decorator} */ class Decorator implements Runnable { private final Runnable task; private final Quota quota; private final CentralExecutor executor; public Decorator(Runnable task, Quota quota, CentralExecutor executor) { this.task = task; this.quota = quota; this.executor = executor; } @Override public void run() { try { task.run(); } catch (Throwable t) { LOGGER.error("Unexpected Interruption cause by", t); } finally { quota.release(); dequeueTo(executor); } } } } /** {@link Policy} */