小工具知识网

当前位置: 首页 > 行业知识 > 关于Java线程池核心内容

行业知识

关于Java线程池核心内容

2026-11-12 01:08:09 来源:互联网转载

线程池的优势

首先,���程池是将多个线程进行池化操作,统一进行管理,这样做有什么好处呢?

()
  • 降低创建、销毁线程的开销 :线程池中维护固定数量的线程,不需要临时进行线程的创建和销毁

  • 提高响应速度 :对于新提交到线程池中的任务,直接使用线程池中的空闲线程可以直接进行处理,不需要等待创建线程

    ()
  • 节省资源:可以重复利用线程。

    什么场景下会用到线程池?

    一般就是多 IO 的场景下需要用到,像 IO 任务很多,比如数据库操作、请求其他接口操作,这都属于 IO 类任务,IO 类任务的特点就是只需要线程去启动一下 IO 任务,之后就等待 IO 结果返回即可,IO 结果返回的时间是比较慢的 ,因此如果只使用单线程去执行 IO 任务的话,由于这个等待时间比较长,那么线程需要一直等待 IO 结果返回,而无法执行其他操作。

    因此在多 IO 场景下,可以使用线程池来加快 IO 任务的执行,开启多个线程同时去启动多个 IO 任务,可以加快 IO 任务的处理速度。

    线程池中重要的参数

    线程池中重要的参数如下:

    • corePoolSize :核心线程数量

    • maximumPoolSize :线程池最大线程数量 = 核心线程数+非核心线程数

    • keepAliveTime :非核心线程存活时间

    • unit:空闲线程存活时间单位(keepAliveTime单位)

    • workQueue :工作队列(任务队列),存放等待执行的任务

      • LinkedBlockingQueue:无界的阻塞队列,最大长度为 Integer.MAX_VALUE

      • ArrayBlockingQueue:基于数组的有界阻塞队列,按FIFO排序

      • SynchronousQueue:同步队列,不存储元素,对于提交的任务,如果有空闲线程,则使用空闲线程来处理;否则新建一个线程来处理任务

      • PriorityBlockingQueue:具有优先级的无界阻塞队列,优先级通过参数Comparator实现。

    • threadFactory :线程工厂,创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等。

    • handler:拒绝策略 ,有4种(也可以自定义拒绝策略)

      • AbortPolicy :直接抛出异常,默认策略

      • CallerRunsPolicy:用调用者所在的线程来执行任务

      • DiscardOldestPolicy:丢弃阻塞队列里最老的任务,也就是队列里靠前的任务

      • DiscardPolicy :当前任务直接丢弃

      对于新加入的任务,线程池如何进行处理?

      对于新加入一个任务,线程池处理流程如下:

      1. 如果核心线程数量未达到,创建核心线程执行

      2. 如果当前运行线程数量已经达到核心线程数量,查看任务队列是否已满

      3. 如果任务队列未满,将任务放到任务队列

      4. 如果任务队列已满,看最大线程数是否达到,如果未达到,就新建非核心线程处理

      5. 如果当前运行线程数量未达到最大线程数,则创建非核心线程执行

      6. 如果当前运行线程数量达到最大线程数,根据拒绝策略处理。

      如何将任务提交到线程池中?

      有两种方式:execute 和 submit

      这两种方式的区别:

      • execute

        • execute 没有返回值

        • execute 无法捕获任务过程中的异常

      • submit

        • submit 会返回一个 Future 对象,用来获取任务的执行结果

        • submit 可以通过 Future 对象来捕获任务中的异常

        execute 方式如下:

        ExecutorService executor = Executors.newFixedThreadPool(5);executor.execute(new Runnable() {   public void run() {       // 执行具体的任务逻辑       System.out.println("Task executed using execute method");  }});executor.shutdown();

        submit 方式如下:

        ExecutorService executor = Executors.newFixedThreadPool(5);Future future = executor.submit(new Callable() {   public String call() {       // 执行具体的任务逻辑       return "Task executed using submit method";  }});try {   String result = future.get(); // 获取任务执行结果   System.out.println(result);} catch (InterruptedException e) {   // 处理中断异常} catch (ExecutionException e) {   // 处理任务执行异常} finally { // 关闭线程池 executor.shutdown();}

        线程池是如何关闭的?

        通过调用线程池的 shutdown() 方法即可关闭线程池

        调用之后,会设置一个标志位表示当前线程池已经关闭,会禁止向线程池中提交新的任务

        去中断所有的空闲线程并且等待正在执行的任务执行完毕(通过调用线程 interrupt() 方法),当线程池中所有任务都执行完毕之后,线程池就会被完全关闭。

        扩展:thread.interrupt() 方法调用后线程不会立即中断。调用 interrupt 只是将被中断线程的中断状态设置为 true,通知被中断的线程自己处理中断,而不是立即强制的让线程直接中断(强制中断不安全)

        当外部调用线程进行中断的命令时,如果该线程处于被阻塞的状态,如 Thread.sleep(),Object.wait(),BlockingQueue#put,BlockingQueue#take 等等时,那么此时调用该线程的 interrupt 方法就会抛出 InterruptedException 异常

        因此,可以通过这个特点来优雅的停止线程(在 《Java多线程核心技术》 一书中说到):将 sleep() 和 interrupt() 搭配使用,来停止线程。

上一篇:Discuz无痕去除教程,轻松移除标识与痕迹,让你的网站焕然一新!

下一篇:psv怎么远程电脑连接服务器?