Executors

1. 介绍

线程池工厂,在实际生产环境中,线程的数量必须得到控制,盲目的大量创建线程对系统性能是有伤害的。

2. 主要方法

2.1 newFixedThreadPool()

​ 该方法返回一个固定线程数量的线程池,该线程池中的线程数量始终不变,当有一个新的任务提交时,线程池中若有空闲线程,则立即执行,若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。

线程数固定,队列无限大

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

示例:

/**
 * newFixedThreadPool
 * 若任务生产的速度远远大于任务处理的速度,阻塞队列的容量就会一直变大,有可能产生内存溢出
 */
public class Test01 {

    @Test
    public void test01() throws Exception{
        ExecutorService es = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 30; i++) {
            es.execute(() -> {
                System.out.println(Instant.now().getEpochSecond() + " " + Thread.currentThread().getId());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        Thread.sleep(13000);
    }

}

2.2 newSingleThreadExecutor()

​ 该方法返回一个只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

2.3 newCachedThreadPool()

​ 该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

2.4 newSingleThreadScheduledExecutor()

​ 该方法返回一个ScheduledExecutorService对象,线程池大小为1。ScheduledExecutorService接口在ExecutorService接口之上扩展了在给定时间执行某任务的功能,如在某个固定的延时之后执行,或者周期性执行某个任务。

    public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1));
    }

2.5 newScheduledThreadPool()

​ 该方法也返回一个ScheduledExecutorService对象,但该线程池可以指定线程数量。

    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }

    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

主要有三种用法,实例:

    /**
     * schedule, 在给定的时间,对任务进行一次调度
     *
     * @throws Exception
     */
    @Test
    public void test01() throws Exception {
        ScheduledExecutorService es = Executors.newScheduledThreadPool(3);

        for (int i = 0; i < 10; i++) {
            es.schedule(() -> {
                System.out.println("run start " + Thread.currentThread().getId());
            }, 2, TimeUnit.SECONDS);
        }
        Thread.sleep(10000);
    }


    /**
     * scheduleAtFixedRate 以任务开始为时间起点,然后每个period周期执行一次任务,
     * 如果执行任务时间超过了周期时间,则任务完成后立即开启下一次任务
     *
     * 下面例子实际周期变成了5
     *
     * @throws Exception
     */
    @Test
    public void test02() throws Exception {
        ScheduledExecutorService es = Executors.newScheduledThreadPool(3);

        for (int i = 0; i < 1; i++) {
            es.scheduleAtFixedRate(() -> {
                System.out.println("run start " + Instant.now().getEpochSecond() + " " + Thread.currentThread().getId());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, 2, 3, TimeUnit.SECONDS);
        }
        Thread.sleep(20000);
    }


    /**
     * scheduleWithFixedDelay 以上一个任务结束后为开始计时,delay时间后,下一个线程执行
     *
     * 下面例子实际周期变成了8
     * @throws Exception
     */
    @Test
    public void test03() throws Exception {
        ScheduledExecutorService es = Executors.newScheduledThreadPool(3);

        for (int i = 0; i < 1; i++) {
            es.scheduleWithFixedDelay(() -> {
                System.out.println("run start " + Instant.now().getEpochSecond() + " " + Thread.currentThread().getId());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, 2, 3, TimeUnit.SECONDS);
        }
        Thread.sleep(20000);
    }

实时内容请关注微信公众号,公众号与博客同时更新:程序员星星
在这里插入图片描述

Executors是Java中提供的一个工具类,用于创建和管理线程池。根据引用[2],Executors类可以创建不同种类的线程池。其中一种是固定大小线程池,在这种线程池中,可以指定线程池的大小,即同时执行的线程数量。通过调用Executors类中的newFixedThreadPool方法,可以创建一个固定大小的线程池。该方法的返回值是一个ExecutorService对象,表示创建的线程池。 引用提到,ExecutorService对象可以执行Runnable对象或者Callable对象代表的线程。Runnable是一个接口,表示一个可以在后台执行的任务,而Callable是一个接口,表示具有返回值的任务。通过将这些任务提交给ExecutorService对象,线程池就可以执行这些任务。 在创建固定大小线程池时,可以指定线程池的大小,即同时执行的线程数量。这些线程会从一个固定大小的线程池中获取,并执行被提交的任务。当任务执行完成后,线程会被返回到线程池中,以供下一个任务使用。 总结起来,Executors是一个Java工具类,用于创建和管理线程池。通过调用其提供的方法,例如newFixedThreadPool,可以创建一个固定大小的线程池,并通过返回的ExecutorService对象来执行Runnable或Callable对象代表的线程。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Java线程池系列--线程池的种类(Executors的用法)](https://blog.csdn.net/feiying0canglang/article/details/120518082)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值