栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

线程及线程池

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

线程及线程池

线程

线程是调度CPU的最小单位,分为KLT与ULT模型。

JVM使用KLT模型,Java与OS保持1:1的映射关系,一个Java线程在OS中也会有一个对应的线程。

         线程状态

         NEW: 新建

         RUNNABLE: 运行

         BLOCKED: 阻塞

         WAITING: 等待

         TIMED_WAITING: 超时等待

         TERMINATED: 终结

         线程状态切换

线程池

         线程属于稀缺资源,如果被无限制创建,不仅会消耗系统资源,还会降低系统的稳定性。

         Java中提供线程池(线程缓存池)对线程进行统一分配、调优和监控。

         频繁的创建和销毁线程,会大大降低系统的效率。

线程池使用场景

         单个任务处理时间比较短;

         需要处理的任务数量很大

线程池优势

         重用存在的线程,减少线程创建、消亡的开销,提高性能;

         提高相应速度。当任务到达直接开始执行,不需要创建;

         提高线程的可管理性

        

线程的实现

  1. 实现Runnable,重写run()方法;
  2. 实现Callable,重写call()方法:Callable接收泛型,同时他执行任务后带有返回内容。

Executor框架

         只拥有一个用于执行Runnable的execute方法。

  • 子接口ExecutorService定义了线程池的具体行为
  1. execute(Runnable command):履行Runnable命令;
  2. submit(task):用来提交Callable或者Runnable任务,并返回代表此任务的Future对象;
  3. shutdown():在完成已提交的任务后封闭办事,不再接管新任务;
  4. shutdownNow():停止所有正在履行的任务并封闭办事;
  5. isTerminated():测试是否所有任务都履行完毕了;
  6. isShutdown():测试该ExecutorService是否已被关闭

重点属性

对线程池的运行状态和线程池中有效线程数量进行控制的一个字段;

包含:线程池的运行状态(runState)和线程池内有效线程的数量(workerCount),它使用Integer:

前三位存储runState,后29位存储workerCount

private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

COUNT_BITS = 32-3 = 29

CAPACITY存储workerCount的上限,即29个1,大约是5亿个线程

线程池存在5种状态

  1. RUNNING
    1. 线程池处于RUNNING状态是,能够接受新任务,以及对已添加的任务进行处理;
    2. 线程池的初始化状态,一旦被创建,就处于RUNNING状态,并且线程池中任务数=0
  2. SHUTDOWN
    1. 线程池处于SHUTDOWN状态,不接收新任务,但能处理已添加的任务;
    2. 调用线程池的shutdown(),线程池由RUNNING -> SHUTDOWN
  3. STOP
    1. 线程池处在STOP状态时,不再接收新任务,不处理已添加的任务,并且会中断正在处理的任务
    2. 调用线程池的shutdownNow(),线程池由RUNNING/SHUTDOWN -> STOP
  4. TIDYING
    1. 当所有的任务已终止,ctl记录的任务数量为0,线程池会变为TIDYING状态,当线程池变为TIDYING状态时,会执行钩子函数terminated()。用户需重载此函数来实现。
    2. 线程池处于SHUTDOWN状态,阻塞队列为空并且线程池中执行的任务也为空,就会有SHUTDOWN -> TIDYING。
    3. 线程池处于STOP状态,线程池中执行的任务为空时,就会由STOP->TIDYING
  5. TERMINATED
    1. 线程池彻底中止,就会变为TERMINATED状态
    2. 线程池处在TIDYING状态时,执行完terminated()之后,就会由TIDYING -> TERMINATED

线程池重要实现

         ThreadPoolExecutor – 默认线程池

         ScheduledThreadPoolExecutor – 定时线程池

构造函数

corePoolSize – 线程池中核心线程数(CPU密集型:CPU核心数+1, IO密集型:2*CPU核心数+1)

当提交一个任务时,线程池会创建一个新线程执行任务,直到当前线程数=corePoolSize;

如果当前线程数为corePoolSize,继续提交的任务会被保存在阻塞队列中,等待被执行;

maximumPoolSize – 线程池中允许的最大线程数

如果当前任务阻塞队列满了,且继续提交任务,则创建新的线程执行任务,直到当前线程数等于maximumPoolSize

keepAliveTime – 线程池维护线程所允许的空闲时间

当线程池中线程> corePoolSize,如果此时没有任务继续提交,核心线程外的线程不会被销毁,而是会等待,直到等待时间大于keepAliveTime

Unit – keepAliveTime的单位

workQueue – 保存等待被执行的任务的阻塞队列,任务必须实现Runnable接口。

threadFactory – 用来创建线程,默认使用Executors.defaultThreadFactory()来创建线程

handler – 线程池饱和策略,当阻塞队列满了,且没有空闲的工作线程,如果继续提交任务,必须采取一种策略来处理该任务

  1. AbortPolicy – 直接抛出异常,默认策略
  2. CallerRunsPolicy – 用调用者所在的线程来执行任务;
  3. DiscardOldestPolicy – 丢弃阻塞队列中最靠前的任务,并执行当前任务;
  4. DiscardPolicy – 直接丢弃任务
  5. 自定义 – 实现RejectExecutionHandler接口

S.D.

源码分析

execute() 提交任务且无返回值,当某一个线程出现异常,不会影响余下线程执行。

  • WorkerCount < corePoolSize, 创建并启动一个核心线程来执行新提交的任务;
  • workerCount>=corePoolSize且workQueue未满,则将任务加到改阻塞队列中;
  • workerCount>=corePoolSize且workerCount
  • workerCount>=maximumPoolSize且workQueue已满,则调用拒绝策略进行处理。

addWorker(Runnable firstTask, Boolean core)

         在线程池中创建一个新的线程并执行。

         firstTask: 用于指定新增的线程执行的第一个任务

         core: true【表示在新增线程时会判断当前活动线程是否少于corePoolSize】

                   false【新增线程前需要判断当前活动线程数是否少于maximumPoolSize】

Worker类

         线程池中每个线程被封装为一个Worker对象,ThreadPool维护的就是一组Worker对象。集成AQS,使用AQS来实现独占锁的功能,且不允许重入(与RenntranrLock的区别)

不允许重入理由:任务在调用setCorePoolSize这样的线程池控制方法时不允许重新获取锁,直接阻塞,以免中断正在运行的线程。

public Future submit() 任务执行完成以后有返回值

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/351599.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号