【并发编程】- Executors 创建线程池

172 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

使用Executors工厂类创建线程池

​ 接口Executor是一种规范,是一种定义,并没有实现任何的功能,所以大多数情况下,需要使用接口的实现类来完成指定的功能,ThreadPoolExecutor类实现了Executor接口,但是ThreadPoolExecutor在使用上并不是方便,在实例化时需要传入多个参数,还需要考虑线程的并发数与线程池运行效率有关的参数,因此使用Executors工厂类创建线程池对象。

使用Executor工厂类的newCachedThreadPool()方法创建无界线程池

使用Executors类的newCachedThreadPool()方法创建的是无界线程池,可以进行线程自动回收,无界线程池是池中存放线程个数是Integer.MAX_VAULE最大值。

public class CachedThreadPoolRun {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("第一阶段开始时间:"+System.currentTimeMillis());
                    Thread.sleep(1000);
                    System.out.println("线程名:"+Thread.currentThread().getName());
                    System.out.println("第一阶段结束时间:"+System.currentTimeMillis());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("第二阶段开始时间:"+System.currentTimeMillis());
                    Thread.sleep(1000);
                    System.out.println("线程名:"+Thread.currentThread().getName());
                    System.out.println("第二阶段结束时间:"+System.currentTimeMillis());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

运行结果如下:

第一阶段开始时间:1653725823036
第二阶段开始时间:1653725823036
线程名:pool-1-thread-2
线程名:pool-1-thread-1
第一阶段结束时间:1653725824036
第二阶段结束时间:1653725824036

从运行结果看出两个线程在相同的时间开始执行,就是创建了2个线程,2个线程之间是异步运行的。

修改运行类代码如下:

public class CachedThreadPoolRun {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 6; i++) {
            int finalI = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("第"+ finalI +"阶段开始时间:"+System.currentTimeMillis());
                        Thread.sleep(1000);
                        System.out.println("线程名:"+Thread.currentThread().getName());
                        System.out.println("第"+finalI+"阶段结束时间:"+System.currentTimeMillis());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
      }
    }

运行结果如下:

1阶段开始时间:16537262731640阶段开始时间:16537262731642阶段开始时间:16537262731644阶段开始时间:16537262731645阶段开始时间:16537262731643阶段开始时间:1653726273164
线程名:pool-1-thread-3
线程名:pool-1-thread-21阶段结束时间:1653726274179
线程名:pool-1-thread-10阶段结束时间:1653726274179
线程名:pool-1-thread-65阶段结束时间:1653726274179
线程名:pool-1-thread-54阶段结束时间:16537262741792阶段结束时间:1653726274179
线程名:pool-1-thread-43阶段结束时间:1653726274179

无论多少个线程,启动线程都是异步运行的。