/** * */ package com.talent.aio.common.threadpool; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.talent.aio.common.threadpool.intf.SynRunnableIntf; /** * 默认的RejectedExecutionHandler实现<br> * 如果Runnable提交被拒绝,本拒绝处理器会将Runnable放到一个队列中,并延时将该Runnable提交给ThreadPool执行。. * * @filename: com.talent.threadpool.DefaultRejectedExecutionHandler * @copyright: Copyright (c)2010 * @company: talent * @author: 谭耀武 * @version: 1.0 * @create time: 2013年10月18日 上午10:05:16 * @record <table cellPadding="3" cellSpacing="0" style="width:600px"> * <thead style="font-weight:bold;background-color:#e3e197"> * <tr> <td>date</td> <td>author</td> <td>version</td> <td>description</td></tr> * </thead> * <tbody style="background-color:#ffffeb"> * <tr><td>2013年10月18日</td> <td>谭耀武</td> <td>1.0</td> <td>create</td></tr> * </tbody> * </table> */ public class DefaultRejectedExecutionHandler<R extends SynRunnableIntf> implements RejectedExecutionHandler { /** The log. */ private static Logger log = LoggerFactory.getLogger(DefaultRejectedExecutionHandler.class); /** The timer seq. */ private static AtomicInteger timerSeq = new AtomicInteger(); /** The rejected count. */ private AtomicLong rejectedCount = new AtomicLong(); /** * The Class SubmitTaskRunnable. */ public static class SubmitTaskRunnable<R extends SynRunnableIntf> implements Runnable { /** The deque. */ LinkedBlockingDeque<SynRunnableIntf> deque = null; /** The executor. */ SynThreadPoolExecutor<SynRunnableIntf> executor = null; /** * Instantiates a new submit task runnable. * * @param deque the deque * @param executor the executor */ public SubmitTaskRunnable(LinkedBlockingDeque<SynRunnableIntf> deque, SynThreadPoolExecutor<SynRunnableIntf> executor) { super(); this.deque = deque; this.executor = executor; } /** * @see java.lang.Runnable#run() * * @重写人: tanyaowu * @重写时间: 2016年11月15日 上午9:07:01 * */ @Override public void run() { while (true) { try { Runnable r = deque.take(); executor.execute(r); log.debug("submit a runnable, {} runnables waiting for submit", deque.size()); } catch (java.lang.Throwable e) { log.error(e.toString(), e); } } } /** * Gets the deque. * * @return the deque */ public LinkedBlockingDeque<SynRunnableIntf> getDeque() { return deque; } /** * Sets the deque. * * @param deque the new deque */ public void setDeque(LinkedBlockingDeque<SynRunnableIntf> deque) { this.deque = deque; } } /** The submit task thread. */ private Thread submitTaskThread; /** The submit task runnable. */ private SubmitTaskRunnable<R> submitTaskRunnable; // public MyTimerTask getMyTimerTask() // { // return myTimerTask; // } // public void setMyTimerTask(MyTimerTask myTimerTask) // { // this.myTimerTask = myTimerTask; // } /** * Instantiates a new default rejected execution handler. * * @param synThreadPoolExecutor the syn thread pool executor */ public DefaultRejectedExecutionHandler(SynThreadPoolExecutor<SynRunnableIntf> synThreadPoolExecutor) { String threadname = synThreadPoolExecutor.getName() + "-rejected-handler-" + timerSeq.incrementAndGet(); LinkedBlockingDeque<SynRunnableIntf> deque = new LinkedBlockingDeque<>(); submitTaskRunnable = new SubmitTaskRunnable<>(deque, synThreadPoolExecutor); submitTaskThread = new Thread(submitTaskRunnable, threadname); submitTaskThread.start(); // myTimerTask = new MyTimerTask(new LinkedBlockingQueue<Runnable>(), synThreadPoolExecutor); // timer.schedule(myTimerTask, 1000); } /** * @see java.util.concurrent.RejectedExecutionHandler#rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) * * @param r * @param executor * @重写人: tanyaowu * @重写时间: 2016年11月15日 上午9:07:01 * */ @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { SynRunnableIntf rr = null; if (r instanceof SynRunnableIntf) { rr = (SynRunnableIntf) r; } else { log.error("只支持SynRunnableIntf"); return; } if (rr.isCanceled()) { log.error("任务已经取消"); return; } rejectedCount.incrementAndGet(); // LinkedBlockingQueue<Runnable> deque = myTimerTask.getQueue(); // synchronized (deque) // { LinkedBlockingDeque<SynRunnableIntf> deque = submitTaskRunnable.deque; // log.debug("deque in rejectedExecution, size:{}, deque:{}", deque.size(), deque.hashCode()); if (deque.contains(r)) { log.debug("{} has contained in deque, deque size is {}", r, deque.size()); } else { if (submitTaskThread == Thread.currentThread()) { log.debug("thread is same--submitTaskThread:{}, currentThread:{}", submitTaskThread, Thread.currentThread()); deque.addFirst(rr); } else { log.debug("thread is diff--submitTaskThread:{}, currentThread:{}", submitTaskThread, Thread.currentThread()); deque.addLast(rr); } } // } log.debug("{} is rejected, {} tasks is waiting!", r, deque.size()); } /** * Gets the submit task thread. * * @return the submit task thread */ public Thread getSubmitTaskThread() { return submitTaskThread; } /** * Sets the submit task thread. * * @param submitTaskThread the new submit task thread */ public void setSubmitTaskThread(Thread submitTaskThread) { this.submitTaskThread = submitTaskThread; } /** * Gets the submit task runnable. * * @return the submit task runnable */ public SubmitTaskRunnable<R> getSubmitTaskRunnable() { return submitTaskRunnable; } /** * Sets the submit task runnable. * * @param submitTaskRunnable the new submit task runnable */ public void setSubmitTaskRunnable(SubmitTaskRunnable<R> submitTaskRunnable) { this.submitTaskRunnable = submitTaskRunnable; } /** * Gets the rejected count. * * @return the rejected count */ public AtomicLong getRejectedCount() { return rejectedCount; } /** * Sets the rejected count. * * @param rejectedCount the new rejected count */ public void setRejectedCount(AtomicLong rejectedCount) { this.rejectedCount = rejectedCount; } }