美文网首页
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