Mercurial > hg > Database > Christie
view src/main/java/christie/codegear/PriorityThreadPoolExecutors.java @ 272:b592fe1d4a4e default tip
create example Attendance
author | matac42 <matac@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 01 Jul 2021 20:41:07 +0900 |
parents | ef5aad739292 |
children |
line wrap: on
line source
package christie.codegear; import java.util.Comparator; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicLong; // https://stackoverflow.com/questions/807223/how-do-i-implement-task-prioritization-using-an-executorservice-in-java-5/42831172#42831172 public class PriorityThreadPoolExecutors { public static ThreadPoolExecutor createThreadPool(int nThreads, int keepAliveTime) { return new PriorityThreadPoolExecutor(nThreads, nThreads, keepAliveTime, TimeUnit.MILLISECONDS); } private static class PriorityThreadPoolExecutor extends ThreadPoolExecutor { private static final int DEFAULT_PRIORITY = 0; private static AtomicLong instanceCounter = new AtomicLong(); public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, int keepAliveTime, TimeUnit unit) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, (BlockingQueue) new PriorityBlockingQueue<ComparableTask>(10, ComparableTask.comparatorByPriorityAndSequentialOrder())); } @Override public void execute(Runnable command) { // If this is ugly then delegator pattern needed if (command instanceof ComparableTask) //Already wrapped super.execute(command); else { super.execute(newComparableRunnableFor(command)); } } private Runnable newComparableRunnableFor(Runnable runnable) { return new ComparableRunnable((CodeGearExecutor) runnable); } @Override protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { return new ComparableFutureTask<>((CodeGearExecutor)runnable, value); } private class ComparableFutureTask<T> extends FutureTask<T> implements ComparableTask { private Long sequentialOrder = instanceCounter.getAndIncrement(); private CodeGearExecutor hasPriority; public ComparableFutureTask(CodeGearExecutor priorityRunnable, T result) { super(priorityRunnable, result); this.hasPriority = priorityRunnable; } @Override public long getInstanceCount() { return sequentialOrder; } @Override public int getPriority() { return hasPriority.getPriority(); } } private static class ComparableRunnable implements Runnable, ComparableTask { private Long instanceCount = instanceCounter.getAndIncrement(); private CodeGearExecutor runnable; public ComparableRunnable(CodeGearExecutor priorityRunnable) { this.runnable = priorityRunnable; } @Override public void run() { runnable.run(); } @Override public int getPriority() { return runnable.getPriority(); } @Override public long getInstanceCount() { return instanceCount; } } private interface ComparableTask extends Runnable { int getPriority(); long getInstanceCount(); static Comparator<ComparableTask> comparatorByPriorityAndSequentialOrder() { return (o1, o2) -> { int priorityResult = o2.getPriority() - o1.getPriority(); return priorityResult != 0 ? priorityResult : (int) (o1.getInstanceCount() - o2.getInstanceCount()); }; } } } }