ExecutorService 四种使用方式

Java 通过 Executors 提供四种线程池, 例如:

  1. newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  2. newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  3. newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
  4. newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

线程池接口 ExecutorService

  1. ExecutorService: 真正的线程池接口。
  2. ScheduledExecutorService: 能和Timer/TimerTask类似,解决那些需要任务重复执行的问题。
  3. ThreadPoolExecutor: ExecutorService的默认实现。
  4. ScheduledThreadPoolExecutor: 继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现。
public class ExecutorServiceTest {
    public static void main(String[] args) {
        // Returns the number of processors available to the Java virtual
        // machine
        // int count = Runtime.getRuntime().availableProcessors();
        // System.out.println(count);

        // 1. 可缓存线程池
        // newCachedThreadPoolMe();
        // 2. 定长线程池
        // newFixedThreadPoolMe();
        // 3. 定长线程池,支持定时及周期性任务执行
        // newScheduleThreadPoolMe();
        // 4. 单线程化的线程池
        // newSingleThreadExecutorMe();
        test();
    }

    // newCachedThreadPool 可缓存线程池
    public static void newCachedThreadPoolMe() {
        ExecutorService pool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; ++i) {
            final int index = i;
            pool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(index);
                }
            });
        }
        pool.shutdown();
    }

    // newFixedThreadPool 定长线程池
    public static void newFixedThreadPoolMe() {
        ExecutorService pool = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 100; ++i) {
            final int index = i;
            pool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(index);
                }
            });
        }
        pool.shutdown();
    }

    // newScheduleThreadPool 定长线程池,支持定时及周期性任务执行
    public static void newScheduleThreadPoolMe() {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);
        for (int i = 0; i < 100; ++i) {
            final int index = i;
            pool.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println(index);
                }
            }, 10, TimeUnit.SECONDS);
        }
        pool.shutdown();
    }

    // newSingleThreadExecutor 单线程化的线程池
    public static void newSingleThreadExecutorMe() {
        ExecutorService pool = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 100; ++i) {
            final int index = i;
            pool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(index);
                }
            });
        }
        pool.shutdown();
    }

    /**
     *  异常处理测试
     */
    public static void test() {
        ExecutorService pool = Executors.newSingleThreadExecutor();
        // pool.execute(new Runnable() {
        // @Override
        // public void run() {
        // int i = 10 / 0;
        // }
        // });

        Future<Boolean> future = pool.submit(new Callable<Boolean>() {
            @Override
            public Boolean call() {
                int i = 10 / 0;
                return true;
            }
        });

        try {
            future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        pool.shutdown();
    }

}

通过 execute 提交的任务,才能将它抛出的异常交给未捕获异常处理器,而通过 submit 提交的任务,无论是抛出的未检查异常还是已检查异常,都将被认为是任务返回状态的一部分。如果一个由 submit 提交的任务由于抛出了异常而结束,那么这个异常将被 future.get() 封装在 ExecutionException 中重新抛出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值