千家信息网

线程池ThreadPoolExecutor有什么作用

发表于:2025-01-27 作者:千家信息网编辑
千家信息网最后更新 2025年01月27日,这篇文章主要讲解了"线程池ThreadPoolExecutor有什么作用",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"线程池ThreadPoolExe
千家信息网最后更新 2025年01月27日线程池ThreadPoolExecutor有什么作用

这篇文章主要讲解了"线程池ThreadPoolExecutor有什么作用",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"线程池ThreadPoolExecutor有什么作用"吧!

一、初始化线程池(4种):

1、newFixedThreadPool()

public final static ExecutorService esPool = Execustor.newFixedThreadPool(50);

特点:corePoolSize == maxPoolSize,使用LinkedBlockingQueue作为堵塞队列;没有可执行任务时不会释放线程池;

2、newCachedThreadPool()

public final static ExecutorService esPool  = Execustor.newCachedThreadPool();

特点:默认缓存60s,线程数可以达到Integer.MAX_VALUE,内部使用SynchronousQueue作为堵塞队列;没有可执行任务时,达到keepAliveTime会释放线程资源,新任务没有执行空闲线程就得重新创建新的线程,会导致系统开销;使用时,注意控制并发数,减少创建新线程数;

3、newScheduleThreadPool()

public final static ExecutorService esPool = Execustor.newScheduleThreadPool(50);

特点:指定时间内周期性内执行所提交的任务,一般用于定时同步数据;

4、newSingleThreadExecutor()

特点:初始化只有一个线程的线程池;内部使用LinkedBlockingQueue作为堵塞队列;

二、源码实现:

1、ThreadPoolExecutor构造器

 public ThreadPoolExecutor(                              int corePoolSize,//核心线程数                              int maximumPoolSize,//最大线程数                              long keepAliveTime,//线程存活时间(必须在线程数在corePoolSize与maximumPoolSie之间时,存活时间才能生效)                              TimeUnit unit,//存活时间的单位                              BlockingQueue workQueue,//堵塞队列                              RejectedExecutionHandler handler//当拒绝处理任务时的策略                           ) {        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,             Executors.defaultThreadFactory(), handler);    }

说明:堵塞队列BlockingQueue:1)ArrayBlockingQueue(数组结构的界限堵塞队列,FIFO);2)LinkedBlockQueue(链表结构的堵塞队列,FIFO);3)SynchronousQueue(不存储元素的堵塞队列,每次插入必须等到另一个线程移除);4)PriorityBlockingQueue(具有优先级的堵塞队列)。

拒绝处理任务的策略RejectedExecutionHandler :1)、ThreadPoolExecutor.AbortPolicy(抛弃当前线程,并抛出RejectedExecutionException异常)2)、ThreadPoolExecutor.DiscardPolicy(抛弃当前线程,不抛出异常);3)、ThreadPoolExecutor.DiscardOldestPolicy(抛弃最前面的任务,然后重新尝试此执行过程);4)、CallerRunnsPolicy(调用线程执行此任务)

2、execute()

 public void execute(Runnable command) {        if (command == null)            throw new NullPointerException();               int c = ctl.get();        //获取当前线程的数量:workerCountOf()        if (workerCountOf(c) < corePoolSize) {            if (addWorker(command, true))//当当前线程数量小于corePoolSize时,就addWorker                return;            c = ctl.get();        }        //如果当前线程处于Running状态;        if (isRunning(c) && workQueue.offer(command)) {            int recheck = ctl.get();            //检查线程池(因为可能在上次检查后,有线程资源被释放),是否有空闲的线程            if (! isRunning(recheck) && remove(command))                reject(command);            else if (workerCountOf(recheck) == 0)                addWorker(null, false);        }        //如果当前线程处于非Running状态;        else if (!addWorker(command, false))            reject(command);    }

3、reject()

   final void reject(Runnable command) {        handler.rejectedExecution(command, this);    }

4、submit()

  public  Future submit(Callable task) {        if (task == null) throw new NullPointerException();        //封装成一个FutureTask对象,FutureTask类实现Runnable接口        RunnableFuture ftask = newTaskFor(task);        //执行execute(),通过execute提交到FutureTask线程池中等待被执行,最终执行FutureTask的run方法        execute(ftask);        return ftask;    }    protected  RunnableFuture newTaskFor(Callable callable) {        return new FutureTask(callable);    }

5、线程状态

       private static final int COUNT_BITS = Integer.SIZE - 3;    //即高3位为111,该状态的线程池会接收新任务,并处理阻塞队列中的任务;        private static final int RUNNING    = -1 << COUNT_BITS;            //即高3位为000,该状态的线程池不会接收新任务,但会处理阻塞队列中的任务;        private static final int SHUTDOWN   =  0 << COUNT_BITS;            //即高3位为001,该状态的线程不会接收新任务,也不会处理阻塞队列中的任务,而且会中断正在运行的任务;        private static final int STOP       =  1 << COUNT_BITS;            //即高3位为010,该状态表示线程池对线程进行整理优化;        private static final int TIDYING    =  2 << COUNT_BITS;        //即高3位为011,该状态表示线程池停止工作;        private static final int TERMINATED =  3 << COUNT_BITS;

6、runWorker()(真正执行任务的接口)

 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 != null || (task = getTask()) != null) {                w.lock();                // If pool is stopping, ensure thread is interrupted;                // if not, ensure thread is not interrupted.  This                // requires a recheck in second case to deal with                // shutdownNow race while clearing interrupt                if ((runStateAtLeast(ctl.get(), STOP) ||                     (Thread.interrupted() &&                      runStateAtLeast(ctl.get(), STOP))) &&                    !wt.isInterrupted())                    wt.interrupt();                try {                    beforeExecute(wt, task);                    Throwable thrown = null;                    try {                        task.run();                    } catch (RuntimeException x) {                        thrown = x; throw x;                    } catch (Error x) {                        thrown = x; throw x;                    } catch (Throwable x) {                        thrown = x; throw new Error(x);                    } finally {                        afterExecute(task, thrown);//啥都没做                    }                } finally {                    task = null;                    w.completedTasks++;                    w.unlock();                }            }            completedAbruptly = false;        } finally {            processWorkerExit(w, completedAbruptly);        }    } protected void afterExecute(Runnable r, Throwable t) { }

感谢各位的阅读,以上就是"线程池ThreadPoolExecutor有什么作用"的内容了,经过本文的学习后,相信大家对线程池ThreadPoolExecutor有什么作用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0