首页 > 其他分享 >JUC

JUC

时间:2023-08-29 20:11:05浏览次数:32  
标签:JUC SCALE 队列 核心 任务 线程 空闲

一、JUC

1.概念

  从Java 5开始,在JDK中多出了java.util.concurrent包(简称:JUC)。

  JUC主要是让开发者在 多线程编程 中更加简单、方便一些。

  通过JDK内置了一些类、接口、关键字,补充完善了JDK对于并发编程支持的“短板”。

2.主要包含功能

  1. Executor:线程池

  2. Atomic:原子操作类

  3. Lock:锁

  4. Tools:信号量工具类

  5. 并发集合:提供了线程安全的集合类。

二、线程池

1.为何使用线程池

对于频繁创建和销毁的线程会消耗系统大量的资源,此时通过使用线程池可以使系统响应时间更快,消耗资源更少

2.概念

线程池是内存中的一块空间,其中存放着实例化的线程对象

当需要用到线程时从线程池中取出,执行完任务或需要销毁时再放回线程池,而不是让线程处于死亡状态。

3.使用线程池的特点

3.1 优点

  1.降低系统资源的消耗。通过重用线程对象,减低由于新建和销毁线程造成的系统资源消耗

  2.提高系统响应的速度。直接从内存中获取线程,比新建线程更快

  3.提供线程的可管理性。通过对线程池中线程数量的限制,避免无限创建线程导致的内存溢出或CPU资源耗尽等问题。

3.2 缺点

  默认情况下,无论是否需要使用线程,线程池中都有一些线程对象,占用内存。

三、JUC中的线程池

1.Executor

线程池的顶级接口

该接口中只有一个execute方法,参数为Runnable类型

public interface Executor {
  void execute(Runnable command);
}

 

 

2.ThreadPoolExecutor

2.1 介绍

是JUC提供的默认的线程池的实现类

2.2 构造方法

四种有参构造

最多7个参数的构造方法

 2.3 参数

  2.3.1 corePoolSize-核心线程数

  创建线程池后,线程池中默认是没有线程的,当从线程池获取线程执行任务时才创建核心线程来执行任务。

  若没有线程数没有达到核心线程数corePoolSize,即使有空闲的核心线程,还是会创建新的核心线程来执行任务,直到达到核心线程数corePoolSize。

  线程池中的线程数达到核心线程数corePoolSize后,从线程池获取空闲的核心线程执行任务。

  2.3.2 workQueue-阻塞队列

  队列:底层是数组或链表实现的,特点是先进先出

  阻塞:队列为空时阻塞获取任务,队列满时阻塞添加任务。

  作用: 当线程池中线程数量达到核心线程数corePoolSize时,且没有空闲的核心线程,再来获取线程执行任务,任务会被添加到缓存任务的阻塞队列workQueue中;

    队列可以设置queueCapacity参数,表示最多能存储的任务数量

  2.3.3 maximumPoolSize-最大线程数

  当所有核心线程都在使用中、阻塞队列的任务也满了,线程池会创建新的线程执行任务,直到线程池中的线程数达到最大线程数maximumPoolSIze;

  线程池中线程数已达到最大线程数且都在使用中、阻塞队列也满了,线程池对于新来的任务就会执行拒绝策略

  2.3.4 keepAliveTime-线程最大空闲时间

  线程池中的空闲线程空闲的时间超过了最大空闲时间keepAliveTime就会被销毁,直到线程池中的线程数等于核心线程数;

  若设置allowCoreThreadTimeOut=true(默认false),核心线程也可以被销毁。

  2.3.5 unit-时间单位

  TimeUnit是枚举类型

public enum TimeUnit {
  //纳秒
  NANOSECONDS(TimeUnit.NANO_SCALE),
  //微妙
  MICROSECONDS(TimeUnit.MICRO_SCALE),
  //毫秒
  MILLISECONDS(TimeUnit.MILLI_SCALE),
  //秒
  SECONDS(TimeUnit.SECOND_SCALE),
  //分钟
  MINUTES(TimeUnit.MINUTE_SCALE),
  //小时
  HOURS(TimeUnit.HOUR_SCALE),
  //天
  DAYS(TimeUnit.DAY_SCALE);
  private static final long NANO_SCALE   = 1L;
  private static final long MICRO_SCALE  = 1000L * NANO_SCALE;
  private static final long MILLI_SCALE  = 1000L * MICRO_SCALE;
  private static final long SECOND_SCALE = 1000L * MILLI_SCALE;
  private static final long MINUTE_SCALE = 60L * SECOND_SCALE;
  private static final long HOUR_SCALE   = 60L * MINUTE_SCALE;
  private static final long DAY_SCALE    = 24L * HOUR_SCALE;
}

  2.3.6 threadFactory-线程工厂

  创建线程对象

  2.3.7 handler-线程池拒绝策略

  前提:只有当任务队列已满,且线程数量已经达到maximunPoolSize才会触发拒绝策略。
  1. AbortPolicy(默认):新提交的任务将被拒绝,并抛出RejectedExecutionException异常。
  2. CallerRunsPolicy:新提交的任务将由提交该任务的线程(调用execute()方法的线程)执行。这意味着提交任务的线程将会暂时充当一个临时线程来执行任务。
  3. DiscardPolicy:新提交的任务将被丢弃,不会抛出任何异常。
  4. DiscardOldestPolicy:新提交的任务将会替换掉等待队列中最旧的任务,然后尝试再次提交该任务。

2.4 创建线程总结

  1. 当线程数小于核心线程数时,创建线程, 直到达到指定的核心线程数。

  2. 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。

  3. 当线程数大于等于核心线程数,且任务队列已满 。

​     i. 若线程数小于最大线程数,创建线程, 直到达到最大线程数 。

​     ii. 若线程数等于最大线程数,抛出异常,拒绝任务。

3. Excutors

Excutors属于一个工具类,可以快速实例化 特定类型 的线程池对象。

返回值都是ExecutorService接口的实现类,底层都调用了ThreadPoolExecutor()

 3.1 SingleThreadExecutor()

方法代码如下:

参数:

  核心线程数和最大线程数都为1

  最大空闲时间为0

  底层为链表的阻塞队列;

效果: 只会创建一个线程执行任务。

 3.2 newFixedThreadPool( int )

方法代码:

核心线程数和最大线程数都是指定的nThreads

底层为链表的阻塞队列

实际线程数量永远维持在nThreads。

 3.3 newCachedThreadPoole()

 参数:

  核心线程数:0

  最大线程数:Integer的最大值(2^31-1)

  最大空闲时间 60 秒

  底层为同步队列的阻塞队列(没有存储空间,只要有任务就必须要有线程执行,如果没有找到空闲的线程就创建新的线程执行)

效果:

  无限容量、线程空闲时间超过60秒就会被销毁、阻塞队列底层为同步队列,没有存储空间,只要有任务就必须有线程来处理,没有空闲的线程就创建新的线程来执行。

 3.4 newScheduleThreadPool()

 参数:

  核心线程数为指定的corePoolSize

  最大线程数为Integer最大值

  最大空闲时间0

  阻塞队列:DelayQueue队列

    底层使用数组实现, 初始容量为16, 超过16个任务, 扩容到之前的1.5倍

可以实现 延时执行 和 周期执行

   3.4.1 延时执行 schedule()

 

标签:JUC,SCALE,队列,核心,任务,线程,空闲
From: https://www.cnblogs.com/giaogiaoyang/p/17665665.html

相关文章

  • AQS和JUC面试题
    【讲义】第2讲:AQS和JUC⼀、ReentrantLock重⼊锁1.1>概述1.2>中断响应lockInterruptibly()1.3>锁申请等待限时tryLock(longtime,TimeUnitunit)1.4>公平锁和⾮公平锁1.5>AQS源码解析⼆、Condition重⼊锁的搭配类三、Semaphore信号量四、ReadWriteLock读写锁五、C......
  • 【转载】JUC常见面试题:Java线程和操作系统线程有什么区别
    【转载】JUC常见面试题:Java线程和操作系统线程有什么区别整理来自于:https://cloud.tencent.com/developer/article/18181511操作系统的用户态和核心态在操作系统中,内存通常会被分成用户空间(Userspace)与内核空间(Kernelspace)这两个部分。当进程/线程运行在用户空间时就处于用......
  • java juc相关
    JUC全称JavaUtilConcurrency,是java中用于并发编程的工具类库,提供了丰富的类和接口,用于管理多线程,支持同步互斥操作。JUC特点:高效性:JUC提供了高度优化的并发控制机制,可以提高多线程应用程序的执行效率和吞吐量。可扩展性:JUC支持灵活的扩展和定制,提供了各种类和接口,可以根据需......
  • JUC
    1、什么是JUCjava.util工具包、包、分类业务:普通的线程代码ThreadRunnable没有返回值、效率相比入Callable相对较低!2、进程和线程回顾进程:一个程序,QQ.exeMusic.exe程序的集合;一个进程往往可以包含多个线程,至少包含一个!Java默认有几个线程?2个mian、GC......
  • JUC并发编程
    一、JUC并发编程1.1.什么是JUC1.1.1.进程和线程、管程进程--资源分配的最小单位指在系统中正在运行的一个应用程序;程序一旦运行就是进程;每一个进程都有它自己的内存空间和系统资源。线程--程序执行的最小单位轻量级进程,系统分配处理器时间资源的基本单元,或者说......
  • JUC并发编程(3)—锁中断机制
    目录1.什么是中断2.源码解读(中断的相关API)3.如何使用中断标识停止线程学习视频:https://www.bilibili.com/video/BV1ar4y1x7271.什么是中断一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止,所以,Thread.stop、Thread.suspend、Thread.resume都已经被......
  • JUC并发编程(1)—CompletableFuture详解
    @目录CompletableFuture介绍1.创建异步任务2.CompletableFutureAPI①.获得结果和触发计算(get、getNow、join、complete)②.对计算结果进行处理(thenApply、handle)③.对计算结果进行消费(thenRun、thenAccept、thenApply)④.对计算速度进行选用(applyToEither、acceptEither......
  • JUC笔记
    JUC并发编程狂神说:https://space.bilibili.com/952564491.什么是JUCJUC就是java.util.concurrent下面的类包,专门用于多线程的开发。源码+官方文档面试高频问!java.util工具包业务:无法通过普通的线程代码Thread实现。Runnable没有返回值、效率相比于Callable相对较......
  • JUC 常用类 ReentrantLock
    ReentrantLock类内部总共存在Sync、NonfairSync、FairSync三个类NonfairSync与FairSync类继承自Sync类Sync类继承自AbstractQueuedSynchronizer抽象类内部类SyncabstractstaticclassSyncextendsAbstractQueuedSynchronizer{//序列号private......
  • JUC包常用类原理
    概要放眼望去,java.util.concurrent包下类大致包括:atomic原子类、锁、并发集合、线程池、工具类。我们挑重要的了解一下。Atomic原子类Java针对并发编程已经有了各种锁,为什么还需要原子类?原子类一定有些特别的应用场景?在很多时候,我们需要的仅仅是一个简单的、高效的、线程安......