前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Executor的介绍及线程池的应用

Executor的介绍及线程池的应用

作者头像
余生大大
发布2022-11-02 14:57:08
2130
发布2022-11-02 14:57:08
举报
文章被收录于专栏:余生大大余生大大

1、Executor

  • Executor的相关关系图

Executors少了一个创建线程池的方法newScheduledThreadPool()

  • 继承和实现关系
代码语言:javascript
复制
public interface ExecutorService extends Executor {}
public abstract class AbstractExecutorService implements ExecutorService {}
public interface ScheduledExecutorService extends ExecutorService {}
public class ThreadPoolExecutor extends AbstractExecutorService {}
public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService {}
代码语言:javascript
复制
区别:

  1.ExecutorService 接口继承了Executor 接口,是Executor 的子接口。


  2.Executor接口中定义了execute()方法,用来接收一个Runnable接口的对象,

       而ExecutorService接口中定义的submit()方法可以接收Runnable和Callable接口对象。


  3.Executor接口中execute()方法不返回任何结果,而ExecutorService接口中submit()方法可以通过一个 Future 对象返回运算结果。


  4.Executor和ExecutorService除了允许客户端提交一个任务,ExecutorService 还提供用来控制线程池的方法。

       比如:调用 shutDown() 方法终止线程池。

  5.Executors 类提供工厂方法用来创建不同类型的线程池。比如: 

     newSingleThreadExecutor() 创建一个只有一个线程的线程池,

     newFixedThreadPool(int numOfThreads)来创建固定线程数的线程池,

     newCachedThreadPool()创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

     newScheduledThreadPool(int corePoolSize) 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
  • Executors简介
    • Executors 是一个工厂类,其提供的是Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类的实例的工厂方法;
    • 提供常用配置的 ExecutorService、ScheduledExecutorService的实现方法;
    • 创建并返回 ThreadFactory 的方法,它可将新创建的线程设置为已知的状态。
    • 将其他非Callable接口的其他类对象,封装成Callable,从而用于默些方法;

2、创建线程池

上面图例和补充里有创建线程池的四种方式。

1. newCachedThreadPool(创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。线程池为无限大)

代码语言:javascript
复制
    public static void main(String[] args) {
        // 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
        Executor cachedThreadPool = Executors.newCachedThreadPool();
        // 循环10次
        for (int i = 0; i < 10; i++) {
            // 初始化index作为线程内输出,要求final
            final int index = i;
            // 等待,让前一个线程执行完成
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 执行任务
            cachedThreadPool.execute(new Runnable() {

                @Override
                public void run() {
                    // 输出线程名称
                    System.out.println(index+" 线程名称:"+Thread.currentThread().getName());
                }
            });
        }
    }

结果:

可以看到使用的一个线程进行的输出,证明在线程执行完成后会被回收重新执行安排的任务

2. newFixedThreadPool(创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

代码语言:javascript
复制
    public static void main(String[] args) {
        // 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int index = i;
            fixedThreadPool.execute(new Runnable() {
                public void run() {
                    try {
                        System.out.println(index);
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        fixedThreadPool.shutdown();
    }

结果:

我们给定长线程池设置了3个线程,就一直是这三个线程在跑

3. newScheduledThreadPool(创建一个定长线程池,支持定时及周期性任务执行。

代码语言:javascript
复制
    public static void main(String[] args) {
        // 创建一个定长线程池,支持定时及周期性任务执行。
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        for (int i = 0; i < 10; i++) {
            scheduledThreadPool.schedule(new Runnable() {
                public void run() {
                    System.out.println("delay 3 seconds "+Thread.currentThread().getName());
                }
            }, 3, TimeUnit.SECONDS);// 3s以后执行
        }
        scheduledThreadPool.shutdown();
    }

结果:

线程池有5个线程,并且在启动后3s后才去执行内容

4.newSingleThreadExecutor (按顺序来执行线程任务   但是不同于单线程,这个线程池只是只能存在一个线程,这个线程死后另外一个线程会补上,继续按顺序执行任务。)

代码语言:javascript
复制
public static void main(String[] args) {
        /**
         * 单线程化的线程池
         */
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            singleThreadExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    Thread.currentThread().setName("Thread i = " + index);
                    System.out.println(Thread.currentThread().getName() + " index = " + index);
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        System.out.println("ssss");
                    }
                }
            });
        }
        singleThreadExecutor.shutdown();
        System.out.println("on the main thread...");

    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、Executor
  • 2、创建线程池
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档