java重构线程池_jdk的线程池实现-ThreadPoolExecutor

前言

一直以来对线程池的概念都挺模糊的,想不明白线程池要如何实现,今天难得周末,就开始查阅资料,研究了一下jdk中的线程池实现,终于解开了我长久以来的疑惑,本文参考文章来自网络,原文连接如下:

参考连接针对jdk6,本文针对jdk8

疑惑

和线程池类似的有一个概念叫连接池,在数据库连接中使用的非常多,连接池比较好理解,一般来说就是一个连接建立完成之后不去关闭它,需要的时候就看获取这个连接的对象并给它的输入流写数据,并从输出流读取响应结果,但是在线程中,一旦某个线程的run方法运行结束之后,线程也就结束了,因此和连接池有很大的不同,这也给我留下了几个疑惑:

如何复用一个线程?

多个线程如何管理?

如何知道某个线程是目前正在运行还是在等待任务?

今天看过jdk中对线程池的实现,才真正明白,线程池和连接池是有很大不同的,使用上也完全不一样。

连接池是每次需要时候的时候,从池里取出一个连接给我们,我们再使用这个连接来交换数据,而线程池并不是在使用的时候从池里取出一个线程对象给我们使用,而是将我们的任务交给线程池,由线程池自己调度任务决定什么时候执行这个任务。

连接池的连接用完之后,会直接放到池内,等待下一个请求连接,而线程池的线程一旦运行完,线程也就结束了,因此不存在放回池内的操作。

一个连接池要持有一定数量的连接,只要保证持有这些未关闭的连接的对象即可,而线程池要持有一定数量的线程,必须保证持有的线程的run方法不会运行结束。

了解了线程池和连接池的区别之后,我们就可以知道,虽然名字很像,但是实际上这两者在原理和概念上是完全不一样的。

jdk1.5以后,新增了一个并发包java.concurrent,这个包里就包含了线程池的实现,最核心的实现类是java.util.concurrent.ThreadPoolExecutor。

实际上jdk从1.5到1.8,java.util.concurrent.ThreadPoolExecutor已经经过多次重构了,1.6和1.8在实现上已经有了很大的不同了,本文针对的是jdk8中的实现。

jdk的线程池实现

我们来看一下jdk中的线程池是如何实现的。

首先要先了解一下类结构,如下图:

50ce0f2246b043888c0ba4b5a1958fee.png

类结构

最顶层的接口是java.util.concurrent.Executor:

public interface Executor {

voidexecute(Runnablecommand);

}

只有一个接口,传入一个Runnable对象,称为指令,线程池就会帮你执行这个指令。

它的一级子接口是java.util.concurrent.ExecutorService:

public interfaceExecutorServiceextendsExecutor{

voidshutdown();

ListshutdownNow();

booleanisShutdown();

booleanisTerminated();

booleanawaitTermination(longtimeout,TimeUnitunit)throwsInterruptedException;

Futuresubmit(Callabletask);

Futuresubmit(Runnabletask,Tresult);

Future> submit(Runnable task);

List> invokeAll(Collection extends Callable> tasks) throws InterruptedException;

List> invokeAll(Collection extends Callable> tasks, long timeout, TimeUnit unit) throws InterruptedException;

TinvokeAny(Collection<?extendsCallable >tasks)throws

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值