美文网首页
Java中的线程池一

Java中的线程池一

作者: 尧字节 | 来源:发表于2020-07-20 21:59 被阅读0次

不读书的人,思想就会停止 !

0. 思维导图

线程池是很多编程语言中都有的,虽然我现在很少写java了,但是对于面试或其他语言,其实都是相通的。
这篇是聊下线程的基本内容,下面是基本的思维导图。


线程池

1. 为什么需要线程池

任何程序,都是一些线程,执行一些任务组成的。任务会很多,如果我们每个任务都创建一个线程去执行。那么随着任务的增加,创建的线程数激增,会有很多问题:

  1. 系统可以创建的线程数不是无限的,因为线程需要占用内存等资源信息。
  2. 不是线程越多越好,线程越多,cpu的核数是固定的,那么多个线程切换的时候,就会发生上下文切换影响性能。
  3. 线程创建和销毁本身也有开销,可能线程创建和销毁的时间比执行任务的时间还长,得不偿失。
public class OneTask { 
 
    public static void main(String[] args) { 
        Thread thread = new Thread(new Task());
        thread.start();
    } 
 
    static class Task implements Runnable { 
        @Override
        public void run() { 
           System.out.println("Thread Name: " + Thread.currentThread().getName());
        } 
    } 
}

如果只有一个线程执行任务那,又存在着cpu利用不充分的问题,比如我们很多任务可能需要IO,在等待IO的时候,线程sleep会让出cpu,从而不利于程序整体性能提升。

一个任务一个线程,系统执行慢;每个任务一个线程,又导致线程过多,导致一系列上述问题。

2. 线程池

为了让系统执行的足够快,又不想创建过多线程,占用过多资源,线程池就应运而生。
线程池有以下好处:

  1. 线程池,故名思意,池子里面创建了一定的线程数,任务来了之后,直接运行,提升响应速度。
  2. 线程池有不少线程是长期存在的,那就不需要过多的线程创建和销毁的开销。
  3. 线程池统筹cpu和内存的使用,线程不够的时候创建,线程空闲下来的时候可以进行销毁,在系统性能和资源占用中保持一个平衡。

3. Java线程池参数说明

这些也是面试中常问的问题,Java中线程池的参数说明如下:

  • corePoolSize 核心线程数
  • maxPoolSize 最大线程数
  • keepAliveTime+ 时间单位 空闲线程的存活时间
  • ThreadFactory 线程工厂,用来创建线程。
  • workQueue 用来存放任务的队列
  • Handler 处理拒绝任务接口实现
    举例:


    线程池

3.1 线程池中线程数

Java中的线程数开始的时候是0 ,当添加任务的时候,首先查看线程池中线程数是否达到了核心线程数(corePoolSize),没有则创建; 如果达到了核心线程数,则看下队列是否满了,如果队列也满了,则判断限制线程数是否达到了最大线程数(maxPoolSize),如果没达到,则继续创建线程;如果达到了,则按照Handler处理拒绝任务的方法来处理。

线程池

从这个图需要注意的:

  1. 线程池初始的状态下是没有线程的,直到来了一个任务。
  2. 非核心线程数的创建是在队列满了之后再创建,如果使用无界队列,比如LinkedBlockingQueue则队列永远不会满,也就不会创建非核心线程,线程池的最大线程数只能为corePoolSize 。

3.2 keepAliveTime

keepAliveTime和时间单位决定了非核心线程的存活时间,如果线程池的线程超过核心线程数,会根据这个时间来销毁非核心线程数,从而减少空闲时候的资源占用;任务多的话,又会根据上图规则来继续创建非核心线程。具备线程数弹性变化的能力。

3.3 ThreadFactory

创建线程的线程工厂,我们如果需要定制线程,比如设置线程的名称等,可以自定义线程工厂来替换默认的线程工厂来创建线程。

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

3.4 workQueue

Java线程池中的任务队列,常用的几种:

LinkedBlockingQueue     

没有容量限制的队列,也真是因为无限,则有可能造成OOM问题。

SynchronousQueue

这个队列很奇怪,没有空间存放数据,来了任务直接交给线程,不进行存放,性能好。也许会奇怪,为啥要又这样队列,我觉得解耦是一方面,解耦生产者和消费者,比如solr的客户端我记得再6.3版本的时候就是用这种队列来提交任务的。

DelayedWorkQueue       

延迟任务队列,当我们做任务定时调度的时候需要,使用此队列。采用堆这种数据结构,可以保持先执行的任务放在队头。
这个队列也是无界队列,也容易引起OOM问题。

四 线程拒绝任务

线程在两种情况下会拒绝任务:

  1. 线程池已经调用shutdown了,相当于已经关闭了线程池,当然再来的任务会被拒绝掉。
  2. 按照刚才线程池中线程的创建过程描述,当线程已经无法再创建非核心线程的时候,再来的任务就会被拒绝掉。

拒绝又分几种拒绝策略:

  1. AbortPolicy: 拒绝抛异常RejectedExecutionException
    这是线程池默认的拒绝策略,如果需要拒绝,则抛出运行时异常:RejectedExecutionException 调用者自行决定如何处理。

  2. DiscardPolicy: 这个比较狠,直接默默地抛弃,不通知,容易丢失任务。

  3. DiscardOldestPolicy: 这个是删除在队列中存活最久的任务,腾出空间给新来的任务,也是默默地抛弃,无提示。

  4. CallerRunsPolicy: 这个是我觉得比较好的策略,它不拒绝,如果满足拒绝条件后,哪个线程执行提交任务,就在哪个线程执行这个任务。你不是提交快慢,那我就交给你执行,这样可以防止提交太快导致无法执行的问题,线程执行了任务就会减慢了提交任务的速度,给线程池执行腾出了时间。

相关文章

  • 19. 线程池

    Android 中的线程池就是 java 中的线程池,即 ThreadPoolExecutor 类。 Java 通...

  • Android 线程池的封装

    GlobalThreadPools.java: 调用: 线程池线程池概念来源于Java中的Executor,它是一...

  • ThreadPoolExecutor的用法

    Java中的线程池 一般我们说起Java中的线程池,其实指的是java.util.concurrent包下的Thr...

  • Java线程池总结

    本篇文章讲述Java中的线程池问题,同样适用于Android中的线程池使用。本篇文章参考:Java线程池分析,Ja...

  • Java线程池详解

    本篇文章讲述Java中的线程池问题,同样适用于Android中的线程池使用。本篇文章参考:Java线程池分析,Ja...

  • Java线程池解析

    参考文章:Java并发:线程池,饱和策略 前言 Java线程池的使用在工作中还是比较常见的,线程池可以减小线程建立...

  • Android中线程池的使用分析

    引言:说起线程池,学习过Java基础的同学估计都不陌生,Android中的线程池其实就是java的线程池。那么为什...

  • Java并发

    一、线程池 线程池:事先将多个线程放到容器中,用的时候不用New线程,直接从池中获取。 Java中的线程池有: 1...

  • Java多线程之线程池深入讲解

    1 线程池介绍 1.1 线程池概念 Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Jav...

  • Java中的ThreadPoolExecutor线程池

    今天简单来和大家一起学习一下,java中的ThreadPoolExecutor线程池。 线程池简介 背书中,线程池...

网友评论

      本文标题:Java中的线程池一

      本文链接:https://www.haomeiwen.com/subject/evtukktx.html