精华内容
下载资源
问答
  • 为什么要用线程池? 减少了创建和销毁线程的次数,每个工作线程...corePoolSize 线程池核心线程数 maximumPoolSize 线程池最大线程数量 keepAliveTime 空闲线程存活时间 unit 空闲线程存活时间单位 workQueue 工.

    为什么要用线程池?

    • 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用
    • 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因线程过多消耗内存,也避免了因线程过少,浪费系统资源

    如何做到每个工作线程都可以被重复利用呢?先看下线程池的工作原理

    原理如上图,线程池有七个核心参数

    • corePoolSize 线程池核心线程数
    • maximumPoolSize 线程池最大线程数量
    • keepAliveTime 空闲线程存活时间
    • unit 空闲线程存活时间单位
    • workQueue 工作队列
    • threadFactory 线程工厂
    • handler 拒绝策略

    线程池之所以能做到重复利用,是因为线程池的核心线程不会被摧毁,执行完任务后会重复利用

    那么线程池是如何保持核心线程不被摧毁呢?

    首先看先线程池是如何处理任务的,如下图

    线程池处理任务

     

    下面我们看下核心部分源码:

    • 当有一个任务添加进来时,线程池会创建一个Worker,Worker是实现Runnable方法的,所以Worker执行时会调用run方法,run方法会接着调用runWoker方法
    • 主要看这一行代码,调用getTask方法获取任务并且执行  while (task != null || (task = getTask()) != null) 
    final void runWorker(Worker w) {
            Thread wt = Thread.currentThread();
            Runnable task = w.firstTask;
            w.firstTask = null;
            w.unlock(); // allow interrupts
            boolean completedAbruptly = true;
            try {
                // 主要看这一行代码,调用getTask方法获取任务并且执行
                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);
            }
        }
    • 看下getTask方法是如何实现的
    private Runnable getTask() {
            boolean timedOut = false; // Did the last poll() time out?
    
            for (;;) {
                int c = ctl.get();
                int rs = runStateOf(c);
    
                // Check if queue empty only if necessary.
                if (rs >= SHUTDOWN && (rs >= STOP || workQueue.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 || workQueue.isEmpty())) {
                    if (compareAndDecrementWorkerCount(c))
                        return null;
                    continue;
                }
    
                try {
                    Runnable r = timed ?
                        workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                        workQueue.take();
                    if (r != null)
                        return r;
                    timedOut = true;
                } catch (InterruptedException retry) {
                    timedOut = false;
                }
            }
        }
    • 主要看这几行代码

    • getTask方法通过调用任务队列的take方法,不断的获取线程

    • 如果任务队列里面数量为0,则会一直阻塞,一直等到有任务加入,从而保证了核心线程不被摧毁
    展开全文
  • Java线程池核心线程数与最大线程数的区别

    万次阅读 多人点赞 2020-06-23 15:20:45
    第一步: 先判断线程池中当前线程数量是否达到了corePoolSize,若未达到,则新建线程运行此任务,且任务结束后将该线程保留在线程池中,不做销毁处理,若当前线程数量已达到corePoolSize,则进入下一步; 第二步: ...

    线程池策略

    corePoolSize:核心线程数;maximunPoolSize:最大线程数
    每当有新的任务到线程池时,
    第一步: 先判断线程池中当前线程数量是否达到了corePoolSize,若未达到,则新建线程运行此任务,且任务结束后将该线程保留在线程池中,不做销毁处理,若当前线程数量已达到corePoolSize,则进入下一步;
    第二步: 判断工作队列(workQueue)是否已满,未满则将新的任务提交到工作队列中,满了则进入下一步;
    第三步: 判断线程池中的线程数量是否达到了maxumunPoolSize,如果未达到,则新建一个工作线程来执行这个任务,如果达到了则使用饱和策略来处理这个任务。注意: 在线程池中的线程数量超过corePoolSize时,每当有线程的空闲时间超过了keepAliveTime,这个线程就会被终止。直到线程池中线程的数量不大于corePoolSize为止。
    (由第三步可知,在一般情况下,Java线程池中会长期保持corePoolSize个线程。)

    饱和策略

    当工作队列满且线程个数达到maximunPoolSize后所采取的策略
    AbortPolicy:默认策略;新任务提交时直接抛出未检查的异常RejectedExecutionException,该异常可由调用者捕获。
    CallerRunsPolicy:既不抛弃任务也不抛出异常,使用调用者所在线程运行新的任务。
    DiscardPolicy:丢弃新的任务,且不抛出异常。
    DiscardOldestPolicy:调用poll方法丢弃工作队列队头的任务,然后尝试提交新任务
    自定义策略:根据用户需要定制。

    展开全文
  • 报错: 线程池初始化参数异常 错误代码: ...错误原因: 核心线程数不能超过最大线程数! 我一开始以为 Runtime.getRuntime().availableProcessors()为12,但实际上是4,这里设置超过4的值就会报错!

    报错: 线程池初始化参数异常

    错误代码:

    错误原因: 核心线程数不能超过最大线程数!  我一开始以为

    Runtime.getRuntime().availableProcessors()为12,但实际上是4,这里设置超过4的值就会报错!
    展开全文
  • 每当有新的任务到线程池时,第一步: 先判断线程池中当前线程数量是否达到了corePoolSize,若未达到,则新建线程运行此任务,且任务结束后将该线程保留在线程池中,不做销毁处理,若当前线程数量已达到corePoolSize...

    线程池策略

    corePoolSize:核心线程数;maximunPoolSize:最大线程数

    每当有新的任务到线程池时,
    第一步: 先判断线程池中当前线程数量是否达到了corePoolSize,若未达到,则新建线程运行此任务,且任务结束后将该线程保留在线程池中,不做销毁处理(如果来了新的任务有空闲的核心线程,则不创建新的线程,使用空闲核心线程执行任务),若当前线程数量已达到corePoolSize,则进入下一步;
    第二步: 判断工作队列(workQueue)是否已满,未满则将新的任务提交到工作队列中,满了则进入下一步;
    第三步: 判断线程池中的线程数量是否达到了maxumunPoolSize,如果未达到,则新建一个工作线程来执行这个任务,如果达到了则使用饱和策略来处理这个任务。注意: 在线程池中的线程数量超过corePoolSize时,每当有线程的空闲时间超过了keepAliveTime,这个线程就会被终止。直到线程池中线程的数量不大于corePoolSize为止。
    (由第三步可知,在一般情况下,Java线程池中会长期保持corePoolSize个线程。)

    饱和策略

    当工作队列满且线程个数达到maximunPoolSize后所采取的策略
    AbortPolicy:默认策略;新任务提交时直接抛出未检查的异常RejectedExecutionException,该异常可由调用者捕获。
    CallerRunsPolicy:既不抛弃任务也不抛出异常,使用调用者所在线程运行新的任务。
    DiscardPolicy:丢弃新的任务,且不抛出异常。
    DiscardOldestPolicy:调用poll方法丢弃工作队列队头的任务,然后尝试提交新任务
    自定义策略:根据用户需要定制。

    到此Java 线程池核心线程数与最大线程数的区别介绍完成。

    展开全文
  • 瓶口:最大线程数 瓶颈:队列 瓶身容量:核心线程线程池SingleThreadPool 和线程池FixedThreadPool wesi
  • java线程池如何合理配置核心线程数? 原创 2019-07-09 22:21:36 5点赞 行思远 码龄2年 关注 线程池合理的线程数你是如何考虑的?这也是之前面试遇到的一个题: 1.先看下机器的CPU核数,然后在设定具体参数: System....
  • 线程池线程数的数量选配依据:IO密集型 + CPU密集型
  • android 线程池核心线程数的确定

    千次阅读 2018-10-11 18:51:25
    1、一般情况下对于计算密集型线程池核心线程数可以设置为CPU的个数...2、对于io(读写文件、读写数据库、网络信息交互等)阻塞密集型的线程池核心线程数可以是无数量上限的,可以重用空闲的线程提高CPU的利用率 ...
  • 1.根据list大小创建核心线程数 最大不超过5个 int poolSize = Math.min(model.getXProductInfoList().size(), 5); 2.写死 new ThreadPoolExecutor(2, 3, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<&...
  • Android应用线程池最大线程数量

    千次阅读 2019-04-23 14:48:24
    Android应用线程池最大线程数量 线程池的大小经验值一般这样设置:(其中N为CPU的核数) 如果是CPU密集型应用,则线程池大小设置为N+1 如果是IO密集型应用,则线程池大小设置为2N+1 那么我们的 Android 应用是...
  • 线程池 核心线程数设定公式

    千次阅读 2020-03-22 17:21:18
    1.先看下机器的CPU核数,然后在设定具体参数: System.out.println(Runtime.getRuntime().availableProcessors()); 即CPU核数 =Runtime.getRuntime().availableProcessors...CPU密集型:核心线程数 = CPU核数+ 1 ...
  • 根据线程数设置公式 最大线程数就是性能最高线程数 因为此时性能已经是最高,再设置比他大的线程数反而性能变低,没有...核心线程数也是基于性能考虑 估算平时的流量需要的线程数,设置核心线程数 ...
  • //核心线程 int arg2=40;//最大线程数量 int arg3=100;//空余保留时间 // 时间单位 ThreadPoolExecutor pool=new ThreadPoolExecutor(arg1, arg2, arg3,TimeUnit.MILLIS...
  • 一、前言对于从事后端开发的同学来说,线程是必须要使用了,因为使用它可以提升系统的性能。但是,创建线程和销毁线程都是比较耗时的操作,频繁的创建和销毁线程会浪费很多CPU的资源。此外,如果每...
  • JAVA定义了原子变量AtomicInteger,实质就是整型数。...- workCount:低的29为表示线程池的工作线程数量。 源码 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));...
  • 一般我们都知道线程池初始化的时候会设置核心线程数CorePoolSize 这个数量代表着我们把要执行的线程丢入到线程池中的工作线程执行 如果当前工作线程数小于等于核心线程数 执行完以后不会把这个工作线程销毁 而是一直...
  • 线程数量是否越多越好呢? 一.CPU密集型 CPU 使用率较高(也就是一些复杂运算,逻辑处理)非常多的情况下,线程数一般只需要CPU核心数的线程就可以了。 这一类型多出现在开发中的一些业务复杂计算和逻辑处理过程中。...
  • 1. 代码查看服务器的核心数 要合理配置线程数首先要知道公司服务器是几核的 代码查看服务器核数: System.out.println(Runtime.getRuntime().availableProcessors()); 2. 合理线程数配置之CPU密集型 CPU密集的意思...
  • if (workerCountOf(c) ) { 活跃线程的数量 核心线程数 if (addWorker(command, true)) 成功加入到worker里 return; 返回 c = ctl.get(); 获取线程池变量 } if (isRunning(c) && workQueue.offer(command)) { 线程池...
  • 线程池合适的线程数量是多少?

    千次阅读 2020-06-28 12:00:33
    本章主要讨论线程池合适的线程数量是多少,以及 CPU 核心数和线程数的关系。我们调整线程池中的线程数量的最主要的目的是为了充分并合理地使用 CPU 和内存等资源,从而最大限度地提高程序的性能。在实际工作中,我们...
  • 线程池核心线程数量过大或者过小有没影响?如何合理地设置线程池的核心线程的数量?这个是在日常开发中程序员在使用线程池时经常需要考虑的问题,下面具体介绍下。 1、当线程池核心线程数量过大或者过小的影响...
  • java线程池线程的重复使用

    千次阅读 2018-10-08 10:36:45
    java线程池之线程的重复使用 Java中提供了多种线程池的操作,再这里记录自己再...1.线程池的创建,指定线程池核心线程和最大线程数量nThreads public static ExecutorService newFixedThreadPool(int nThreads) { ...
  • 提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配、调优和监控 (1)线程池中submit()和exectute()方法的区别? execute():只能...
  • 多线程可以快速执行任务的原理 因为服务器是拥有多个处理器核心的。...当线程池接收到任务时,会先创建核心线程数去处理任务,直至待处理的任务数量超过任务队列长度和核心线程数之和时,会继续创建非核心线程直至
  • 线程池核心线程数量过大或者过小有没影响?如何合理地设置线程池的核心线程的数量?这个是在日常开发中程序员在使用线程池时经常需要考虑的问题,下面具体介绍下。 1、当线程池核心线程数量过大或者过小的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 59,065
精华内容 23,626
关键字:

线程池核心线程数量