Java学习笔记(多线程):任务和线程池(未完成)

tech2025-11-07  6

本文是个人的学习笔记,主要参考以下资料: Java核心技术 卷一,Cay S.Horstmann著,林琪、苏钰涵等译,机械工业出版社出版

1、代表线程池的类:ExecutorService1.1、ExecutorService的常用方法1.1.1、常规方法,提交任务,关闭线程池1.1.2、定时线程池的方法(Scheduled)1.1.3、任务组批量执行 1.2、使用Executors静态方法生成线程池


构造一个线程的代价巨大,因为涉及与操作系统的交互。所以,如果一个程序中有大量生命期很短的线程,那势必会影响都系统的运行。

Java中每个Runnable我们都可以看成是一个任务,我们可以在线程执行完一个Runnable的run方法之后不去销毁这个线程,而是让这个线程继续去执行其他Runnable的run方法。这样就可以用少量线程执行多个任务。


1、代表线程池的类:ExecutorService

ExecutorService可以看成是代表线程池的类,其他各种类型的线程池都是它的子类。

线程池有各种类型,比如只有一个线程的线程池,固定大小的线程池和可扩充大小的线程池等等。Java中构建这些线程池都可以通过Executors的静态方法获取。

1.1、ExecutorService的常用方法

1.1.1、常规方法,提交任务,关闭线程池

向线程池提交任务

我们有三个方法向线程池提交任务

Future<T> submit(Callable<T> task);Future<T> submit(Runnable task);Future<T> submit(Runnable task, T result);void execute(Runnable command); 上面的三个方法都会返回Future的对象。返回值即可一定程度代表参数中的任务,我们可以通过Future来了解任务的在线程池中的一些状态,或者一定程度的控制任务的执行。 其中,前三个方法最后都是调用 execute方法来执行线程,这个方法来源是Executor。 Future具体内容可以看这篇文章https://blog.csdn.net/sinat_38393872/article/details/106267242 关闭线程,关闭线程池

1.shutdown():关闭线程池。停止接收任务,但是会执行完已提交的任务。等所有任务都执行完再关闭线程池。 2.shutdownNow:立刻强制关闭线程池。

1.1.2、定时线程池的方法(Scheduled)

这类方法都定义在ScheduledExecutorService中,方法比较少,主要是在时间上控制任务的执行。比如提交任务后延迟一段时间再执行任务等。

1.ScheduledFuture<V> schedule(Callable<V> task, long time, TimeUnit unit):提交一个任务,但是即使有空闲线程,任务也不会立刻占有线程,而是会等待time个unit时间单位后才开始占用线程。我做过实验,创建一个ScheduledExecutorService线程池,使用该方法延迟提交一个任务,然后立刻使用普通方法提交一个任务,系统会先执行第二个任务。等第二个任务执行完,且第一个任务定时已过,那第一个任务会开始执行。 2.ScheduledFuture<V> schedule(Runnable<V> task, Long time, TimeUnit unit):同上一个一样。 3.ScheduledFuture<V> scheduleAtFixedRate(Runnable<V> task, Long time, Long period, TimeUnit unit):提交一个任务,该任务在time个unit时间单位后开始尝试占用线程。之后会每隔period个unit时间单位会执行一次任务,执行次数理论无上限。该间隔是指任务从获得线程的那一刻开始,到下一次获得线程的时刻,与任务执行时间无关。任务提交后,尽管线程池会不断地执行这个任务,但这个任务并没有一直占用着一个线程,若任务执行结束且处于间隔期间,那一定是没有占用线程的。 4.scheduleWithFixedDelay(Runnable task, long initialDelay, long delay, TimeUnit unit):与上一个类似,不同点是,上一个方法的间隔是上一次任务开始执行时间到下一次任务开始的时间。该方法的间隔是上一次任务执行完成时间到下一次任务的开始时间。

1.1.3、任务组批量执行

ExecutorService中还定义了一些批量执行任务组的方法。

1.<T> List<Future<T>> invokeAll​(Collection<? extends Callable<T>> tasks):一次性执行集合中的所有任务,返回代表这些任务的Future列表,Future的顺序与参数集合中的顺序相同。 2.<T> T invokeAny​(Collection<? extends Callable<T>> tasks):一次性执行集合中所有任务,但是只返回其中一个任务的返回值,一般来说是第一个结束的任务的返回值。

1.2、使用Executors静态方法生成线程池

下面是Executors静态方法生成的线程池。

方法描述newCachedThreadPool优先使用已创建的线程执行任务,如果线程不够,再创建线程,可同时存在无限多的线程数。当一个线程的空闲时间超过60s时,这个线程会被销毁。该线程池可大量提高数量多,短周期的任务场景。newFixedThreadPool创建一个固定大小的线程池。如果某一时间任务过多,没有足够的线程,那这些任务会被放到一个队列中等待,直到获取到空闲线程去执行任务。这些线程创建以后不会被销毁,除非线程池关闭或者发生未知错误。如果线程是因为后者被销毁,并且这一时间也有任务需要线程去执行,那会有一个新的线程被创建出来去执行任务。newWorkStealingPoolnewSingleThreadExecutor单线程池,通常是用来测试性能。newScheduledThreadPool提供了一些方法来操控线程的执行周期。newSingleThreadScheduledExecutor和newScheduledThreadPool一样,但是是单线程池。


最新回复(0)