首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

干货,一篇文章搞懂Java线程池所有问题

干货,一篇文章搞懂Java线程池所有问题,学习Java线程池知识点,没搞懂的小伙伴,可以仔细阅读,对理解Java线程池有极大的帮助。

1、如何实现Java中的线程池?

在Java中的线程池的“线程”,就是被抽象成了一个静态内部类Worker,它是基于AQS实现,存储在线程池的HashSetworkers成员变量中而需要执行的任务,因此存放在成员变量workQueue中。为此,整个线程池实现的底层思想就是:从workQueue中一直取出需要执行的任务,放在Workers中进行处理。如需要执行的任务需要存放在成员变量里。

2、创建线程池有几个构造参数?

Java中的线程池的创建灵活,可以通过不同的参数进行配置,创建出任务不同的线程池,参数如下:

CorePoolSize:线程池的核心线程数

MaximumPoolSize:线程池允许的最大线程数

KeepAliveTime:超过核心线程数时闲置线程的存活时间

workQueue:任务执行前保存任务队列,保存由execute方法进行提交的Runnable任务。

3、线程池中的线程是怎么创建的?一开始就随着线程池的启动创建吗?

当然不是。初始化后不启动Worker是默认的线程池,只有当有请求时才会启动。每当调用execute()方法添加任务时,线程池会做出以下判断:。

如果正在运行的线程数小于corePoolSize,则立即创建一个线程来运行此任务。

如果正在运行的线程数大于或等于corePoolSize,则将此任务放入队列中。

如果此时队列已满,并且正在运行的线程数小于maximumPoolSize,那么仍然需要创建一个非核心线程来立即运行任务。

如果队列已满,且正在运行的线程数大于或等于maximumPoolSize,则线程池将抛出异常。

返回执行异常。当一个线程完成一个任务时,它会从队列中取出下一个任务来执行。当一个。

线程无事可做,当它超过一定时间(keepAliveTime)时,线程池将判断。

如果当前正在运行的线程数大于corePoolSize,则此线程将被停止。因此,在线程池的所有任务完成后,它最终将缩小到corePoolSize的大小。

4、既然提到可以通过配置不同参数创建出不同的线程池,那么Java中默认实现好的线程池又有哪些呢?请比较它们的异同

1.SingleThreadExecutor线程池这个线程池只有一个核心线程在工作,这相当于用一个线程串行地执行所有任务。在。如果唯一的线程异常结束,则会有一个新的线程替换它。。这个线程池保证所有任务的执行顺序按照提交任务的顺序执行。

corePoolSize:1,只有一个核心线程在工作

maximumPoolSize:1

keepAliveTime:0L

workQueue:newLinkedBlockingQueue(),其缓冲队列是无界的。

2.FixedThreadPool线程池FixedThreadPool是一个只有核心线程的固定大小线程池。每次提交任务时创建一个线程,直到线程达到线程池的最大大小。一旦线程池的大小达到极大值,它将保持不变。如果一个线程由于执行异常而结束,线程池将添加一个新的线程。FixedThreadPool主要针对一些非常稳定和固定的常规并发线程,主要用于服务器。

corePoolSize:nThreads

maximumPoolSize:nThreads

keepAliveTime:0L

workQueue:newLinkedBlockingQueue(),其缓冲队列是无界的。

3.CachedThreadPool线程池CachedThreadPool是一个无界线程池。如果线程池的大小超过了处理任务所需的线程,那么将回收一些空闲线程(60秒内未执行任务)。当任务数量增加时,这个线程池可以智能地添加新线程来处理任务。线程池的大小完全取决于操作系统(或JVM)可以创建的最大线程大小。SynchronousQueue是一个阻塞队列,缓冲区为1。缓存型池子通常用于执行一些生存期很短的异步型任务,因此在一些面向连接的daemon型SERVER中用得不多。但对于短命的异步任务,它是Executor的首选。

corePoolSize:0

maximumPoolSize:Integer.MAX_VALUE

keepAliveTime:60L

workQueue:newSynchronousQueue(),一个是缓冲区为1的阻塞队列。

4.ScheduledThreadPool线程池ScheduledThreadPool:核心线程池固定,大小无限的线程池。此线程

池支持定时以及周期性执行任务的需求。创建一个周期性执行任务的线程池。如果闲置,非核心线程池会在DEFAULT_KEEPALIVEMILLIS时间内回收。

corePoolSize:corePoolSize

maximumPoolSize:Integer.MAX_VALUE

keepAliveTime:DEFAULT_KEEPALIVE_MILLIS

workQueue:newDelayedWorkQueue()

5、如何在Java线程池中提交线程?

线程池最常用的提交任务的方法有两种:

1.execute():ExecutorService.execute方法接收一个Runable实例,它用来执行一个任务:

2.submit():ExecutorService.submit()方法返回的是Future对象。可以用isDone()来查询Future是否已经完成,当任务完成时,它具有一个结果,可以调用get()来获取结果。也可以不用isDone()

进行检查就直接调用get(),在这种情况下,get()将阻塞,直至结果准备就绪。

Java如何入门

Java300集的学习路线图完整版

根据学习线路学习,这套教程是专门为零基础的学生制作的。它适合于零基础的准备开始Java开发的学生。视频中穿插了许多实用的项目。每一个知识点都以浅显易懂的方式讲解,由浅入深。

不仅适合零基础初学者,有经验的程序员也可以做巩固学习。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230307A06UM400?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券