Thread And Timer

    xiaoxiao2025-08-26  55

    线程池

    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)创建出来的。

    转载请注明原文地址: https://ju.6miu.com/read-1302004.html
    最新回复(0)