这篇文章主要介绍“java线程池的状态有几种”,在日常操作中,相信很多人在java线程池的状态有几种问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java线程池的状态有几种”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!RUNNING 初始化以后就是这种状态 SHUTDOWN 不再接收新任务 把已有任务完成后就变状态 STOP 不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。 TIDYING(收拾/整理) 没有任务没有线程 有钩子方法 terminated() TERMINATED 线程池的具体实现 ThreadPoolExecutor 默认线程池 ScheduledThreadPoolExecutor 定时线程池 提交任务###参数解释线程池中的核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePoolSize;如果当前线程数为corePoolSize,继续提交的任务被保存到阻塞队列中,等待被执行;如果执行了线程池的prestartAllCoreThreads()方法,线程池会 提前创建并启动所有核心线程。程执行任务,前提是当前线程数小于maximumPoolSize;线程池维护线程所允许的空闲时间。当线程池中的线程数量大于corePoolSize的时 候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待 的时间超过了keepAliveTime; unit keepAliveTime的单位;了如下阻塞队列: 1、ArrayBlockingQueue:基于数组结构的有界阻塞队列,按FIFO排序任务; 2、LinkedBlockingQuene:基于链表结构的阻塞队列,按FIFO排序任务,吞 吐量通常要高于ArrayBlockingQuene; 3、SynchronousQuene:一个不存储元素的阻塞队列,每个插入操作必须等到 另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于 LinkedBlockingQuene; 4、priorityBlockingQuene:具有优先级的无界阻塞队列; threadFactory 它是ThreadFactory类型的变量,用来创建新线程。默认使用 Executors.defaultThreadFactory() 来创建线程。使用默认的ThreadFactory来创建线程 时,会使新创建的线程具有相同的NORM_PRIORITY优先级并且是非守护线程,同时也设 置了线程的名称。线程池的饱和策略,当阻塞队列满了,且没有空闲的工作线程,如果继续提交任务,必 须采取一种策略处理该任务,线程池提供了4种策略: 1、AbortPolicy:直接抛出异常,默认策略; 2、CallerRunsPolicy:用调用者所在的线程来执行任务; 3、DiscardOldestPolicy:丢弃阻塞队列中靠最前的任务,并执行当前任务; 4、DiscardPolicy:直接丢弃任务; 上面的4种策略都是ThreadPoolExecutor的内部类。 当然也可以根据应用场景实现RejectedExecutionHandler接口,自定义饱和策略,如 记录日志或持久化存储不能处理的任务。如果在执行execute方法一直处于running状态 执行流程如下如果wokeCount 如果workerCount >= corePoolSize,且线程池内的阻塞队列未满,则将任务添 加到该阻塞队列中;如 果 workerCount >= corePoolSize && workerCount 如果workerCount >= maximumPoolSize,并且线程池内的阻塞队列已满, 则根 据拒绝策略来处理该任务, 默认的处理方式是直接抛异常。 注意一下addWorker(null,false) 创建线程但是没有传入任务,因为之前已经把任务放到队里里面了firstTask参数 用 于指定新增的线程执行的第一个任务线程池中的每一个线程被封装成一个Worker对象,ThreadPool维护的其实就是一组 Worker对象.Worker类继承了AQS,并实现了Runnable接口,注意其中的firstTask和thread属 性:firstTask用它来保存传入的任务;thread是在调用构造方法时通过ThreadFactory来创 建的线程,是用来处理任务的线程。在调用构造方法时,需要把任务传入,这里通过 getThreadFactory().newThread(this); 来 新 建 一 个 线 程 , newThread 方 法 传 入 的 参 数 是 this,因为Worker本身继承了Runnable接口,也就是一个线程,所以一个Worker对象在 启动的时候会调用Worker类中的run方法。Worker继承了AQS,使用AQS来实现独占锁的功能。为什么不使用ReentrantLock来 实现呢?可以看到tryAcquire方法,它是不允许重入的,而ReentrantLock是允许重入的:lock方法一旦获取了独占锁,表示当前线程正在执行任务中;如果正在执行任务,则不应该中断线程;如果该线程现在不是独占锁的状态,也就是空闲的状态,说明它没有在处理任务, 这时可以对该线程进行中断;线程池在执行shutdown方法或tryTerminate方法时会调用interruptIdleWorkers 方法来中断空闲的线程,interruptIdleWorkers方法会使用tryLock方法来判断线程 池中的线程是否是空闲状态;之所以设置为不可重入,是因为我们不希望任务在调用像setCorePoolSize这样的 线程池控制方法时重新获取锁。如 香港云主机果使用ReentrantLock,它是可重入的,这样如果 在任务中调用了如setCorePoolSize这类线程池控制的方法,会中断正在运行的线 程。 所以,Worker继承自AQS,用于判断线程是否空闲以及是否可以被中断。 此外,在构造方法中执行了setState(-1);,把state变量设置为-1,为什么这么做呢? 是因为AQS中默认的state是0,如果刚创建了一个Worker对象,还没有执行任务时,这时 就不应该被中断,看一下tryAquire方法:在Worker类中的run方法调用了runWorker方法来执行任务,runWorker方法的代码如下:总结一下runWorker方法的执行过程:while循环不断地通过getTask()方法获取任务;getTask()方法从阻塞队列中取任务;如果线程池正在停止,那么要保证当前线程是中断状态,否则要保证当前线程不是 中断状态;调用task.run()执行任务;如果task为null则跳出循环,执行processWorkerExit()方法;runWorker方法执行完毕,也代表着Worker中的run方法执行完毕,销毁线程。 这里的beforeExecute方法和afterExecute方法在ThreadPoolExecutor类中是空的,留给 子类来实现。到此,关于“java线程池的状态有几种”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注开发云网站,小编会继续努力为大家带来更多实用的文章!
相关推荐: 电脑桌面图标只有文字没有图标如何解决
这篇文章主要讲解了“电脑桌面图标只有文字没有图标如何解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“电脑桌面图标只有文字没有图标如何解决”吧!解决方法/步骤:1.直接调出任务管理器,随后在进程中找到explo…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。