zoukankan      html  css  js  c++  java
  • 线程池

    线程池

      最近在做关于Cpu的进程管理软件,展示CPU、磁盘、内存的信息,用到java中的线程,读到了有关线程池的相关文章。

    线程池的工作原理:

      其实线程池是一个调度任务的工具。在初始化线程池会给定线程池的大小,假设现在我们有 1000 个线程任务需要运行,而线程池的大小为 10~20,在真正运行任务的过程中他肯定不会创建这1000个线程同时运行,而是充分利用线程池里这 10~20 个线程来调度这1000个任务。这里的 10~20 个线程最后会由线程池封装为 ThreadPoolExecutor.Worker 对象,而这个 Worker 是实现了 Runnable 接口的,所以他自己本身就是一个线程。

      如果创建了一个核心线程、最大线程数、阻塞队列都为2的线程池。假设线程池已经完成了预热,也就是线程池内部已经创建好了两个线程 Worker。如果让一个线程池运行一个任务,它的流程是怎样的?第一步是生产者,也就是任务提供者他执行了一个 execute() 方法,本质上就是往这个内部队列里放了一个任务。

      之前已经创建好了的 Worker 线程会执行一个 while 循环 ---> 不停的从这个 内部队列里获取任务。(这一步是竞争的关系,都会抢着从队列里获取任务,由这个队列内部实现了线程安全。)

      获取得到一个任务后,其实也就是拿到了一个 Runnable 对象(也就是 execute(Runnabletask) 这里所提交的任务),接着执行这个 Runnable 的 run() 方法,而不是 start()。

      while 循环,从 getTask() 方法中一直不停的获取任务。

      拿到任务后,执行它的 run() 方法。

      这样一个线程就调度完毕,然后再次进入循环从队列里取任务并不断的进行调度。

      在单个线程的线程池中一但抛出了未被捕获的异常时,线程池会回收当前的线程并创建一个新的 Worker;它也会一直不断的从队列里获取任务来执行,但由于这是一个消费线程,根本没有生产者往里边丢任务,所以它会一直 waiting 在从队列里获取任务处,所以也就造成了线上的队列没有消费,业务线程池没有执行的问题。

      为什么线程池在调度的时候执行的是 Runnable 的 run() 方法,而不是 start() 方法,

      执行了 start() 方法后操作系统才会创建一个独立的线程来运行,而 run() 方法只是一个普通的方法调用。在线程池这个场景中却恰好就是要利用它只是一个普通方法调用。

      查考文章:原文

  • 相关阅读:
    带编译器的codeblocks下载地址
    联想拯救者s15k重装w10系统教程
    w10下Oracle 11g完全干净卸载
    小机房的树(codevs 2370)
    NOIP[2015] 运输计划(codevs 4632)
    ⑨要写信(codevs 1697)
    酒厂选址(codevs 1507)
    美丽的大树(codevs 2124)
    乘法运算(codevs 3254)
    货车运输(codevs 3287)
  • 原文地址:https://www.cnblogs.com/zhao-teng-ass/p/11055815.html
Copyright © 2011-2022 走看看