032 线程池

一 . 概述

  我们创建线程的代价是相当大的,线程池就是一个减少线程创建代价的事物.核心就是完成线程创建的任务.

    当然当我们将线程的创建工作都交给了线程池,那么线程池就拥有了线程的控制权.


三 .线程池的分类

  在JUC之中将线程池分成四类:

  我们看一下类的结构.

public class PoolTest {
    public static void main(String[] args) {
        //线程池
        //1 带缓冲区的线程池
        Executor ex1 = Executors.newCachedThreadPool();
        //创建单一线程的线程池
        Executor ex2 = Executors.newSingleThreadExecutor();
        //创建固定数量的线程池
        Executor ex3 = Executors.newFixedThreadPool(5);
        //创建带调度的线程池
        Executor ex4 = Executors.newScheduledThreadPool(3);
    }
}

上面介绍了我们最为常见的四种线程池.


三 . 带缓冲的线程池

  解析: 当下线程池创建的时候会创建一定数量的缓存线程,当需要线程的时候直接从线程池中获取线程.

     当线程池中的线程不足时,直接创建新的线程,当使用完,设置线程的终止时间倒计时,如果到倒计时还没用处,直接终结线程.

  因此,我们能看到带缓冲的线程池是我们比较常用的一种.


四. 单一线程的线程池

  很简单,就是这个线程池只维护一个线程,当过多的线程任务到来的时候,会排队接收线程任务.


五 .固定线程数的线程池

  这个也十分的简单,就是线程池的线程数量是固定的,当过多的线程到来的时候,会排队等待.


六 . 任务调度的线程池

  线程池可以按照指定的延迟进行线程的调度,比如每一秒调度一个线程.


七.线程池的基本使用

  我们使用带缓冲区的线程池为例:

  

@Test
    public void test() throws Exception {
        // 创建线程池
        ExecutorService service = Executors.newCachedThreadPool();
        // 提交线程任务

        for (int x = 0; x < 3; x++) {
            service.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("我们提交的是Runnable接口,没有返回值");
                }

            });
        }
        List<Future<Integer>> resultList = new ArrayList<>();
        for (int x = 0; x < 3; x++) {
            int temp = x;
            Future<Integer> result = service.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    return temp;
                }
            });
            resultList.add(result);
        }
        //关闭线程池
        service.shutdown();
        // 主线程休眠1秒
        Thread.sleep(1000);
        // 拿出结果
        resultList.stream().forEach(e -> {
            try {
                System.out.println(e.get());
            } catch (InterruptedException | ExecutionException e1) {
                e1.printStackTrace();
            }
        });

    }

在这里我们需要注意的就是,我们使用线程池的时候,可以传递Runnable接口的线程任务,此时是没有返回值的/

  也可以传入Callable接口的线程任务.此时我们是可以获取返回值的.

  注意: Future接口的返回值的获取的阻塞式的.


猜你喜欢

转载自www.cnblogs.com/trekxu/p/9016894.html