当前位置: 首页 > 后端技术 > Java

JAVA的线程池详解

时间:2023-04-01 15:31:07 Java

一位热爱技术的立花右京师兄立花左京前言说完了线程池,我们先来说说线程,什么是线程,每个程序都是一个单独的进程,比如QQ,网易Cloud,我们如何理解线程?实际上,一个进程至少包含一个线程作为程序的最小执行单元,比如迅雷同时下载多个文件。线程池为什么要使用线程池?顾名思义,线程池是由多个线程组成的。它的作用是减少线程的建立和销毁。它与数据库连接池具有相同的概念。以减少连接和释放,从而降低消耗,提高效率。适用场景很多朋友都是刚接触多线程,一直没有了解多线程的实际应用。应该应用在哪里?其实多线程是否适用还是要看你的具体业务。比如显示详情页需要80ms。分8步查询不同表的数据,每步耗时10ms。如果是同步执行,则需要顺序执行汇编数据。这时候如果引入多线程查询,返回数据只需要10多ms。创建方法Executors类提供了六种不同的线程池创建方案。参数都是默认方法,最后传给ThreadPoolExecutor实例。这种方法虽然简单方便,但也有缺点。如果开发者不理解或无意中使用,可能会导致OOM。阿里手册也明确规定,不允许直接使用Executors创建线程池,而是使用ThreadPoolExecutor自定义线程池参数。1.Executors第一个出现的是Executors。让我们先展示它的方法。从图中可以看出,它给出了六种创建线程的方式。请按照两组的顺序阅读1。)newCachedThreadPool可缓存的线程池。它的核心线程数是0,但是线程总数是Integer的最大值,也就是说是最大值。它使用SynchronousQueue作为队列,不保留任务,任务到达后直接创建线程,可能会造成OOM。2)newFixedThreadPool定长线程池。它是一个可以控制并发数的线程池。如果任务到达后所有线程都被占用,则将其加入队列。它使用LinkedBlockingQueue作为队列,这是一个无界队列。任务会不断加入队列,可能会造成OOM。3)newScheduledThreadPool调度线程池。您可以设置固定或延迟执行任务。当线程空闲时,会直接使用。如果线程被占用,则会创建一个新线程。它使用DelayedWorkQueue作为队列,可以保证任务只有在时间到了才会执行。4)newSingleThreadExecutor为单线程线程池。创建一个只有一个线程的线程池。如果有多个任务进来,只执行一个,其他的进入等待队列,遵循先进先出的规则。它使用LinkedLockingQueue作为等待队列,可能会导致OOM。5)newSingleThreadScheduledExecutor是一个单线程线程池,用于周期性执行任务。6)newWorkStealingPool工作窃取线程池。如果有线程A和B,一共分配了5个任务,A分配了4个,B分配了1个。如果B执行完任务而A还没有完成,它会主动去找A窃取任务执行。2.ThreadPoolExecutor第二个是ThreadPoolExecutor,可以自定义不同的参数来达到目的,一共有七个参数,依次显示。publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnitunit,BlockingQueueworkQueue,ThreadFactorythreadFactory,RejectedExecutionHandlerhandler)**参数分析:1)corePoolSize:核心线程数**①核心线程未全部创建时,即使有空闲线程也不会被重用,会不断创建新的核心线程。②核心线程即使空闲也不会被回收,除非allowCoreThreadTimeOut(booleanvalue)设置为true。③在项目初始化时调用prestartCoreThread()方法预先创建线程,避免执行任务时创建线程效率低下。2)maximumPoolSize:线程总数。核心线程+临时线程的总数就是总线程数的在线数。当核心线程不够用时,会创建临时线程协助处理任务。临时线程空闲超过指定时间就会被回收。3)keepAliveTime:超时时间4)unit:过期时间的单位,可以指定秒、小时、分钟5)workQueue:如果工作队列中没有空闲线程,则将新的任务加入到工作队列中等待为了执行,队列分为有界和无界队列,无界队列其实有一个上限,就是Integer的最大值。6)threadFactory:线程工厂,用于实现线程的生成方式,定义是否为守护线程,主要用于设置线程名称。7)handler:rejectionpolicy当等待队列满时,将执行拒绝策略,提供四种方式选择①ThreadPoolExecutor.AbortPlicy:抛出异常,默认策略。②ThreadPoolExecutor.DiscardPolicy:直接丢弃任务,但不抛异常。③ThreadPoolExecutor.DsicardOldestPolicy:丢弃最早的任务,将新任务加入队列。④ThreadPoolExecutor.CallerRunsPolicy:线程池所在线程处理任务,自己处理。使用ThreadPoolExecutor正确创建线程池staticThreadFactoryfactory=newThreadFactoryBuilder().setNameFormat("TachibanaSakyo").build();staticThreadPoolExecutorexecutor=newThreadPoolExecutor(10,20,60,TimeUnit.SECONDS,newArrayBlockingQueue<>(30),factory,newThreadPoolExecutor.AbortPolicy());publicstaticclassMyThreadimplementsRunnable{@Overridepublicvoidrun(){System.out.println("TachibanaSakyo");}}publicstaticvoidmain(String[]args){MyThreadmyThread=newMyThread();执行者提交(我的线程);调用线程执行的方法有两种,提交和执行。submit的作用是通过return获取返回值,execute没有返回值。