美文网首页
Thread And Timer

Thread And Timer

作者: 探戏者 | 来源:发表于2017-06-21 11:44 被阅读0次

线程池

ThreadPoolExecutor
这个类是最基层的线程池类。Executors创建的线程池底层都是用这个实现的。ThreadPoolExecutor的构造方法如下:

    public ThreadPoolExecutor(int corePoolSize,    
                              int maximumPoolSize,  
                              long keepAliveTime,  
                              TimeUnit unit,  
                              BlockingQueue<Runnable> workQueue,  
                              ThreadFactory threadFactory,  
                              RejectedExecutionHandler handler) {  
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||  
            keepAliveTime < 0)  
            throw new IllegalArgumentException();  
        if (workQueue == null || threadFactory == null || handler == null)  
            throw new NullPointerException();  
        this.corePoolSize = corePoolSize;  
        this.maximumPoolSize = maximumPoolSize;  
        this.workQueue = workQueue;  
        this.keepAliveTime = unit.toNanos(keepAliveTime);  
        this.threadFactory = threadFactory;  
        this.handler = handler;  
    }  

corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略

任务不断添加导致如下的参数按照先后顺序实际size不断增加:
corePoolSize --> workQueue --> maximumPoolSize --> handler处理新添加的线程
具体描述:
当一个任务通过execute(Runnable)方法欲添加到线程池时:

  • 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
  • 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
  • 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
  • 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。
  • JDK默认的 handler 为new AbortPolicy(),直接throw 一个异常,内部实现如下:
        public static class AbortPolicy implements RejectedExecutionHandler {
        /**
         * Creates an <tt>AbortPolicy</tt>.
         */
        public AbortPolicy() { }
        
        /**
         * Always throws RejectedExecutionException.
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         * @throws RejectedExecutionException always.
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        throw new RejectedExecutionException();
        }
        }  

Executors
封装好的线程池工具。
Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)

Executors.newFixedThreadPool(int)(固定大小线程池)

Executors.newSingleThreadExecutor()(单个后台线程)

Executors.newScheduledThreadPool(int corePoolSize) (可以指定延迟后执行线程任务,看源码workQueue是自动扩容的,maximumPoolSize是Integer.MAX_VALUE。)

定时器

Timer
单线程执行任务。如果任务中存在未捕捉的异常。这整个timer全部挂掉。后面的任务不会执行。
Timer 拥有 TaskQueue 和 TimerThread 两个属性。TaskQueue 队列存放添加的所有任务。TimerThread用来执行任务。但是主要执行代码如下:

      private void mainLoop() {
            while (true) {
                try {
                    TimerTask task;
                    boolean taskFired;
                    synchronized(queue) {
                        // Wait for queue to become non-empty
                        while (queue.isEmpty() && newTasksMayBeScheduled)
                            queue.wait();
                        if (queue.isEmpty())
                            break; // Queue is empty and will forever remain; die
    
                        // Queue nonempty; look at first evt and do the right thing
                        long currentTime, executionTime;
                        task = queue.getMin();
                        synchronized(task.lock) {
                            if (task.state == TimerTask.CANCELLED) {
                                queue.removeMin();
                                continue;  // No action required, poll queue again
                            }
                            currentTime = System.currentTimeMillis();
                            executionTime = task.nextExecutionTime;
                            if (taskFired = (executionTime<=currentTime)) {
                                if (task.period == 0) { // Non-repeating, remove
                                    queue.removeMin();
                                    task.state = TimerTask.EXECUTED;
                                } else { // Repeating task, reschedule
                                    queue.rescheduleMin(
                                      task.period<0 ? currentTime   - task.period
                                                    : executionTime + task.period);
                                }
                            }
                        }
                        if (!taskFired) // Task hasn't yet fired; wait
                            queue.wait(executionTime - currentTime);
                    }
                    if (taskFired)  // Task fired; run it, holding no locks
                        task.run(); //这里是关键。调用的是run(),而不是start();
                } catch(InterruptedException e) {
                }
            }
        }
    }   

task.run()证明是一个单线程在干这件事。

ScheduledExecutorService
是一个线程池。具有周期性调用的功能。是由
Executors.newScheduledThreadPool(int corePoolSize)创建出来的。

相关文章

网友评论

      本文标题:Thread And Timer

      本文链接:https://www.haomeiwen.com/subject/fyizqxtx.html