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() 方法只是一个普通的方法调用。在线程池这个场景中却恰好就是要利用它只是一个普通方法调用。

      查考文章:原文

  • 相关阅读:
    codeforces 814B An express train to reveries
    codeforces 814A An abandoned sentiment from past
    codeforces 785D D. Anton and School
    codeforces 785C Anton and Fairy Tale
    codeforces 791C Bear and Different Names
    AOP详解
    Spring集成JUnit测试
    Spring整合web开发
    IOC装配Bean(注解方式)
    IOC装配Bean(XML方式)
  • 原文地址:https://www.cnblogs.com/zhao-teng-ass/p/11055815.html
Copyright © 2011-2022 走看看