当你想要创建线程来执行任务的时候, 如果你new Thread()来创建的话,就太low了,
第一 频繁的new Thread会大量消耗系统性能,
第二 大量重复创建线程会导致线程太多导致系统OOM
第三 相比ExecutorService来说 thread少了很多线程操作
executorService用来创建线程池, 线程池有两个好处, 第一可以节省程序大量的重复创建销毁线程操作(因为一个请求连接就会创建一个线程,执行完后会销毁线程, 创建和销毁操作会占用程序响应时间和内存),第二可以做异步执行方法, 不占用程序执行时间以便快速响应
核心线程数一般设置为cpu数
Executor
Executor是一个接口,他只有一个方法,该方法用于执行Runnable(线程), 但是他有很多子接口
其中最常用的一个子接口就是 ExecutorService, 他在Executor接口上定义了终止,提交等任务方法
executor方法:执行Ruannable类型的任务, 无返回值
submit方法: 执行Ruannable类型或者Callable类型的任务,并返回Future, Future是线程执行结果对象。注意,Callable类型中有一个call()方法,他可以返回任务的执行结果。Ruannable类型中是run()方法, 他的返回值类型是void。使用Future对象的get()方法获取线程结果, 可以看到 如果是Runnable的话, 是没有返回值的, 但是他也可以返回Future对象。 注意, get()方法会阻塞主线程直到获取到返回结果
hutdown方法:停止接收线程请求, 等待当前线程池中任务结束后关闭线程池
shutdownNow方法: 停止接口线程请求,如果线程池中还有线程未执行或正在执行,尝试中断操作,注意,只是尝试,不保证是否中断成功, 关闭线程池并返回未执行线程列表, 注意, 返回的线程列表中是不包括正在执行的线程的
(注意: 线程池的关闭操作需要根据实际开发场景决定是否关闭, 如果是一个固定线程池的话个人理解是不需要关闭的,因为如果池子满了的话其余线程是会阻塞等待的,如果你每次都关闭线程池,那么还会有创建线程池的场景,有点得不偿失,至于什么时候需要关闭, 就是当你的线程池是Integer最大值的线程池,并且当前这个线程池已经创建了很多的线程时, 你可以去关闭这个池子在去重新创建一个)
invokeAll方法:只可以传入Callable集合, 执行完毕并返回每一个Callable线程执行结果返回一个Future集合对象
invokeAny方法: 同样只可以传入Callable集合,不同的是执行完毕后只返回其中某一个线程的执行结果(随机的,不确定的)
Executors是一个线程工厂类, 通过它可以创建线程池
Executors提供四种线程池:
Executors.newFixedThreadPool() 创建固定数量的线程池
创建一个固定数量的线程池, 多余的任务请求会排队等待
Execuors.newCachedThreadPool() 创建可缓存线程池
创建一个缓存线程池,如果线程池长度超过执行任务数, 那么会自动回收空闲线程(60秒无任务),并且如果有空闲线程的话,新的任务会使用空闲线程,不需要在重新创建线程, 如果当前线程池无法满足任务量, 会无限创建线程, 直到超过Integer.MAX_VALUE,他有两个构造, 该线程池是无法指定大小的
Executors.newScheduledThreadPool() 创建定长线程池, 可延时执行
创建一个可以指定核心线程数的线程池,可以支持延时执行和定时执行, 注意,返回的是 ScheduledExecutorService对象
Executors.newSingleThreadExecutor() 创建单线程的线程池
创建一个只有一个线程的线程池, 剩余线程等待,但是可以保证任务顺序, 同样有两个构造
Executors提供了上述4中线程池,可以根据自己选择使用,不过官网是不推荐使用Executors的,因为其中线程最大线程数是Integer最大值,造成系统资源浪费, 而且一直创建线程池的话容易造成系统OOM, 当然,如果你创建的是固定数量的线城池(newFixedThreadPool) 还是比较方便的,比较都封装好了也不需要你自己去new了, 他们的底层还是调用new ThreadPoolExecutor方法的。
ExecutoService
1 手动new一个线程池,
2 构造就比较灵活, 我们可以根据自己的场景配置自己合适的参数, 有些参数可以配置,也可以不配置,当然, 配置的时候要根据系统大小和应用场景配置
3 此方式可以应对一些比如核心队列,临时队列,任务队列都满了的情况,可以使用它来返回一些信息或者是执行一些逻辑
4 可以自己定义创建线程的属性啥的,比如名字
ScheduledThreadPoolExecutor
它也是一个线程池, 只不过他可以支持循环执行和延迟执行线程, 同样可以使用线程工厂 Executors来创建(创建方式在文档上边), 也可以自己创建, 他也是一个Integer最大值的线程池, 你可以设置他的核心线程数
它有四个方法, 可以支持Callable和Runnable
schedule (Callable task, long delay, TimeUnit timeunit)
schedule (Runnable task, long delay, TimeUnit timeunit)
scheduleAtFixedRate (Runnable, long initialDelay, long period, TimeUnit timeunit)
scheduleWithFixedDelay (Runnable, long initialDelay, long period, TimeUnit timeunit)
标签:执行,Executors,创建,可以,Callable,线程,ExecutorService From: https://blog.csdn.net/Small_white_528/article/details/142479896