Java深入学习14:Java线程池

Java深入学习15:Java线程池

一、线程池的作用

  线程池提供一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁等额外开销,提交了响应的速度。

二、类关系

Java线程池相关的接口和类均在 java.util.concurrent 包下,其相关关系(部分)如下

三、Executors类以及相关常用方法介绍

1-Executors类简介:简单的说是线程方法的工具类,提供了 创建线程池等方法。

2-ExecutorService 类创建线程池

        //创建缓存线程池,线程数量不固定,可以自动调节线程数量
        ExecutorService executor1 = Executors.newCachedThreadPool();
        //创建缓存线程池,并且只有一个线程数量
        ExecutorService executor2 = Executors.newSingleThreadExecutor();
        //创建缓存线程池,并指定线程数量
        ExecutorService executor3 = Executors.newFixedThreadPool(5);

3-ExecutorService 类执行线程

public class ThreadPoolTest {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        //创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(5);

        //方法1-1:Future<?> submit(Runnable task);有返回值
        executor.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " runnable");
            }
        });
        //方法1-2:<T> Future<T> submit(Callable<T> task);有返回值
        Future<Object> future = executor.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                System.out.println(Thread.currentThread().getName() + " callable");
                return new Random().nextInt(100);
            }
        });
        System.out.println(future.get());
        //方法2-1:void execute(Runnable command)。没有返回值
        executor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " Runnable");
            }
        });

        //关闭线程池。ExecutorService
        executor.shutdown();
    }

}

4-ScheduledExecutorService 使用

public class ThreadPoolTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //1-创建线程池
        ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(5);
        //2-执行线程,延迟2秒执行
        for(int i=0; i<10; i++){
            scheduledExecutor.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            },2,TimeUnit.SECONDS );
        }
        //3-关闭线程池
        scheduledExecutor.shutdown();
    }
}
------------------------------日志输出------------------------------
pool-1-thread-1
pool-1-thread-1
pool-1-thread-1
pool-1-thread-1
pool-1-thread-3
pool-1-thread-3
pool-1-thread-5
pool-1-thread-2
pool-1-thread-4
pool-1-thread-1

//日志说明:线程只有5个,并且会重复使用

 5- submit()和execute()区别

  1- 接收的参数不一样

  2- submit有返回值,而execute没有。用到返回值的例子,比如说我有很多个做validation的task,我希望所有的task执行完,然后每个task告诉我它的执行结果,是成功还是失败,如果是失败,原因是什么。

  3- submit方便Exception处理。意思就是如果你在你的task里会抛出checked或者unchecked exception,而你又希望外面的调用者能够感知这些exception并做出及时的处理,那么就需要用到submit,通过捕获Future.get抛出的异常。

END

原文地址:https://www.cnblogs.com/wobuchifanqie/p/12546995.html