线程池改造,使得任务执行严格按照先后顺序执行

public class BookRunnable implements Runnable, Comparable<BookRunnable> {

    private Book book;

    private HandleService handleService;

    public BookRunnable(){
    }

    public BookRunnable(Book book){
        this.book = book;
        if(null == handleService){
            handleService = AppContext.getBean("handleService");
        }
    }

    @Override
    public int compareTo(@NotNull BookRunnable o) {
        if(this.book.getTaskTime().getTime() > o.book.getTaskTime().getTime()){
            return 1;
        }
        if(this.book.getTaskTime().getTime() < o.book.getTaskTime().getTime()){
            return -1;
        }
        return 0;
    }

    @Override
    public void run() {
        handleService.handleMessage(book);
    }
}

private final class Worker extends AbstractQueuedSynchronizer implements Runnable{
       
    private static final long serialVersionUID = 6138294804551838833L;

    
    final Thread thread;
    
    Runnable firstTask;
    
    volatile long completedTasks;

    BlockingQueue<Runnable> queue;

    Runnable runningTask;

    
    Worker(Runnable firstTask) {
        setState(-1);
        this.firstTask = firstTask;
        this.thread = getThreadFactory().newThread(this);
    }

    Worker(Runnable firstTask, BlockingQueue<Runnable> queue) {
        setState(-1);
        this.firstTask = firstTask;
        this.thread = getThreadFactory().newThread(this);
        this.queue = queue;
    }

    
    @Override
    public void run() {
        try {
            //新建线程时等待10秒再执行,防止第一条线程执行的任务没有按照优先级排序直接执行了
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        runWorker(this);
    }
}

private boolean addWorker(Runnable firstTask, boolean core, BlockingQueue<Runnable> queue) {
    retry:
    for (int c = ctl.get();;) {
        // Check if queue empty only if necessary.
        if (runStateAtLeast(c, SHUTDOWN) && (runStateAtLeast(c, STOP) || firstTask != null || queue.isEmpty())){
            return false;
        }

        for (;;) {
            if (workerCountOf(c) >= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK)){
                return false;
            }

            if (compareAndIncrementWorkerCount(c)){
                break retry;
            }
            // Re-read ctl
            c = ctl.get();
            if (runStateAtLeast(c, SHUTDOWN)){
                continue retry;
            }
            // else CAS failed due to workerCount change; retry inner loop
        }
    }

    boolean workerStarted = false;
    boolean workerAdded = false;
    Worker worker = null;
    try {
        worker = new Worker(firstTask, queue);
        final Thread thread = worker.thread;
        if (thread != null) {
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                int c = ctl.get();
                if (isRunning(c) || (runStateLessThan(c, STOP) && firstTask == null)) {
                    // precheck that t is startable
                    if (thread.isAlive()) {
                        throw new IllegalThreadStateException();
                    }
                    workers.add(worker);
                    int s = workers.size();
                    if (s > largestPoolSize) {
                        largestPoolSize = s;
                    }
                    workerAdded = true;
                }
            } finally {
                mainLock.unlock();
            }
            if (workerAdded) {
                thread.start();
                workerStarted = true;
            }
        }
    } finally {
        if (! workerStarted){
            addWorkerFailed(worker);
        }
    }
    return workerStarted;
}

private Runnable getTask(Worker w) {
    // Did the last poll() time out?
    boolean timedOut = false;

    for (;;) {
        int c = ctl.get();
        // Check if queue empty only if necessary.
        if (runStateAtLeast(c, SHUTDOWN) && (runStateAtLeast(c, STOP) || w.queue.isEmpty())) {
            decrementWorkerCount();
            return null;
        }

        int wc = workerCountOf(c);

        // Are workers subject to culling?
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

        if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 && w.queue.isEmpty())) {
            if (compareAndDecrementWorkerCount(c)){
                return null;
            }
            continue;
        }

        try {
            //每个线程从自己的队列中取出任务
            Runnable r = timed ? w.queue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : w.queue.take();
            if (r != null){
                return r;
            }
            timedOut = true;
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}

final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();
    Runnable task = w.firstTask;
    w.firstTask = null;
    w.unlock(); // allow interrupts
    boolean completedAbruptly = true;
    try {
        while ((task = getTask(w)) != null) {
            w.lock();
            w.runningTask = task;
            
            if ((runStateAtLeast(ctl.get(), STOP) || (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted()){
                wt.interrupt();
            }
            try {
                beforeExecute(wt, task);
                try {
                    task.run();
                    afterExecute(task, null);
                } catch (Throwable ex) {
                    afterExecute(task, ex);
                    throw ex;
                }
            } finally {
                task = null;
                w.runningTask = null;
                w.completedTasks++;
                w.unlock();
            }
        }
        completedAbruptly = false;
    } finally {
        processWorkerExit(w, completedAbruptly);
    }
}

@Override
public void execute(Runnable command) {
    BookRunnable bookCommand = (BookRunnable)command;
    ConcurrentMap<Worker, Integer> concurrentMap = Maps.newConcurrentMap();
    for(Worker worker : workers){
        concurrentMap.put(worker, worker.queue.size());
        BookRunnable runningTask = (BookRunnable)worker.runningTask;
        if(runningTask != null){
            //判断正在执行的任务编号与传入的任务编号是否一致,如果一致则加入当前队列
            if(runningTask.getBook().getTreeCode().equals(bookCommand.getBook().getTreeCode())){
                return;
            }
        }
        for(Runnable runnable: worker.queue){
            BookRunnable bookRunnable = (BookRunnable)runnable;
            //判断队列中是否存在相同的任务号,如果存在加入队列并返回
            if(bookRunnable.getBook().getTreeCode().equals(bookCommand.getBook().getTreeCode())){
                worker.queue.offer(command);
                return;
            }
        }
    }

    int c = ctl.get();
    //如果工作的线程数小于核心线程数,新建工作线程,队列与线程关系绑定
    if (workerCountOf(c) < corePoolSize) {
        BlockingQueue<Runnable> queue = new PriorityBlockingQueue<>();
        queue.offer(command);
        if (addWorker(command, true, queue)){
            return;
        }
    }

    List<Map.Entry<Worker, Integer>> list = Lists.newArrayList(concurrentMap.entrySet());
    list.sort(Comparator.comparing(Map.Entry :: getValue));
    Worker worker = list.get(0).getKey();
    //如果最小队列长度大于等于4 并且工作线程数小于最大线程数,新建工作线程,队列与线程关系绑定
    if(worker.queue.size() >= TASK_NUMBER && workerCountOf(c) < maximumPoolSize){
        log.info("工作线程数:{}, 最小队列队列长度:{}" , workerCountOf(c), worker.queue.size());
        BlockingQueue<Runnable> queue = new PriorityBlockingQueue<>();
        queue.offer(command);
        if (addWorker(command, false, queue)){
            return;
        }
    }
    //如果如果线程数达到核心线程数,找一个队列长度最小的线程,并把任务添加到对应的队列中
    worker.queue.offer(command);
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值