线程池

线程池:是一种利用池化技术思想来实现的线程管理技术,主要是为了复用线程、便利地管理线程和任务、并将线程的创建和任务的执行解耦开来。

线程池哪有写优点呢?

  • 降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。
  • 提高响应速度:任务到达时,无需等待线程创建即可立即执行。
  • 提高线程的可管理性:线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分配、调优和监控。
  • 提供更多更强大的功能:线程池具备可拓展性,允许开发人员向其中增加更多的功能。比如可以允许任务延期执行或定期执行。

 

Executors线程池工具类创建线程池底层也是通过ThreadPoolExecutor创建线程池。所以ThreadPoolExecutor时非常核心的一个线程池类

任务进入优先级:先用核心线程完成任务,再进阻塞队列;阻塞队列满了,但是线程池的线程数量小于maxPoolExecutor,此时增加新的任务,会立即执行新的任务,而不会从队列中取任务。

一、ThreadPoolExecutor

线程池类图关系:

 

Executor 为函数式接口,线程池最顶级的接口。
1 public interface Executor {
2     void execute(Runnable command);
3 }
execute和submit方法不同?submit底层调用了execute,差别在RunnableFuture<T> ftask= new FautureTask(callable)这行代码。

1 execute只能提交Runnable类型的任务,submit既能提交Runnable又能提交Callable类型的任务

2 异常的捕捉:execute会直接抛出异常,submit会吃掉异常,通过Future的get方法将异常抛出

3 返回值:execute没有返回值,submit有返回值

 


ExecutorService接口:

复制代码
public interface ExecutorService extends Executor {


    void shutdown();


    List<Runnable> shutdownNow();


    boolean isShutdown();

   
    boolean isTerminated();


    <T> Future<T> submit(Callable<T> task);


    <T> Future<T> submit(Runnable task, T result);


    Future<?> submit(Runnable task);

    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;


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


    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException;


    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}
复制代码

FutureTask

 

 

 

FutureTask实现了RunnableFuture接口,RunnableFuture实现了Runnable和Future接口。

线程池使用时,callable当作参数传入submit方法中,方法体中callable传入FutureTask构造器中,再调用execute方法,参数为FutureTask。

非线程池使用时,FutureTask当作参数传入Thread线程构造器中。

中。FutureTask.get方法获得返回值。

 

ThreadPoolExecutor

复制代码
public ThreadPoolExecutor(int corePoolSize, //核心线程数
                              int maximumPoolSize,  //最大线程数
                              long keepAliveTime,  //空闲时存活时间
                              TimeUnit unit,       //空闲时存活时间单位
                              BlockingQueue<Runnable> workQueue   //阻塞队列

ThreadFactory threadFactory, //线程工厂,定义如何新建线程
                              RejectedExecutionHandler handler      //拒绝策略

)
复制代码

 

AbstractExecutorService

实现了ExecutorService接口,只有实现了submit、invokeAny、invokeAll方法。

二、Executors

线程池的使用
线程池的创建方法有7钟,但是可以分为两大类
一类是通过Executors实现
一类是通过ThreadPoolExecutors实现

Executors底层也是通过new ThreadPoolExecutors()创建线程池,所以线程池底层为ThreadPoolExecutors。

 

 

①单线程线程池:Single Thread Executor : 只有一个线程的线程池,因此所有提交的任务是顺序执行,

代码:Executors.newSingleThreadExecutor()
说明:创建大小为1的固定线程池,同时执行任务(task)的只有一个,其它的(任务)task都放在LinkedBlockingQueue中排队等待执行。

 

②缓存线程池(变长):Cached Thread Pool :短时间内处理大量工作的线程池,会根据任务数量产生对应的线程,并试图缓存线程以便重复使用,如果线程超过60秒内没执行,那么将被终止并从池中删除,

代码:Executors.newCachedThreadPool()

说明:使用时,放入线程池的task任务会复用线程或启动新线程来执行,注意事项:启动的线程数如果超过整型最大值后会抛出RejectedExecutionException异常,启动后的线程存活时间为一分钟。


③固定线程数线程池:Fixed Thread Pool : 拥有固定线程数的线程池,如果没有任务执行,那么线程会一直等待,

代码:Executors.newFixedThreadPool()
说明:创建固定大小(nThreads,大小不能超过int的最大值)的线程池,缓冲任务的队列为LinkedBlockingQueue,大小为整型的最大数,当使用此线程池时,在同执行的任务数量超过传入的线程池大小值后,将会放入LinkedBlockingQueue,在LinkedBlockingQueue中的任务需要等待线程空闲后再执行,如果放入LinkedBlockingQueue中的任务超过整型的最大数时,抛出RejectedExecutionException。(newFixedThreadPool的参数指定了可以运行的线程的最大数目,超过这个数目的线程加进去以后,不会运行。其次,加入线程池的线程属于托管状态,线程的运行不受加入顺序的影响。)

 

④周期性线程的线程池 : Scheduled Thread Pool : 用来调度即将执行的任务的线程池,

代码:Executors.newScheduledThreadPool()


⑤单线程周期性线程池:Single Thread Scheduled Pool : 只有一个线程,用来调度执行将来的任务,代码:
Executors.newSingleThreadScheduledExecutor()
说明:线程keepAliveTime为0,缓存任务的队列为DelayedWorkQueue,注意不要超过整型的最大值。

 

⑥WorkStealingPool(n):Java 8 新增创建线程池的方法,创建时如果不设置任何参数,则以当前机器处理器个数作为线程个数,此线程池会并行处理任务,不能保证执行顺序。

 

一旦你创建了一个线程池,你就可以往池中通过不同的方法提交执行任务

submit方法该可提交 Runnable 或者 Callable 到线程池中,返回一个 Future 实例表示任务的状态,如果你提交一个 Runnable 但参数没有T result,那么如果任务完成后 Future 对象返回 null。

execute方法传递Runnable到线程池中,没有返回值。

shutdown方法,等待线程都执行完毕后终止线程池,shutdownNow() 的方法来强制关闭线程池,执行中的线程也会被中断,所有尚未被执行的任务也将不会再执行。

 

posted @   堤苏白  阅读(102)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示