线程池的使用

作者: 奔跑吧李博 | 来源:发表于2019-01-03 00:46 被阅读2次
为什么要用线程池?

1.创建/销毁线程伴随着系统开销,使用多线程过于频繁的创建/销毁线程,会很大程度上影响处理效率;这里线程池可以复用线程,线程池可以避免性能降低。
2.线程并发数量过多,抢占系统资源从而导致阻塞;这里线程池可以显示最大线程数量。
3.对线程进行一些简单的管理

各种线程池的创建方式:

1.创建缓存线程池:

        //创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

内部实现方式:

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

2.创建单线程池:

 //创建一个线程的线程池,保证任务执行顺序和添加任务顺序一致
        ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();

内部实现方式:

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

3.创建定长线程池

//创建定长线程池
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

内部实现方式:

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

4.创建周期线程池

 //创建一个定长线程池,定时及周期性任务执行
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);

内部实现方式:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
使用线程池执行任务:
        threadPool.execute(new Runnable() {
            @Override
            public void run() {

            }
        });
使用线程池关闭任务:

原理是遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程

        cachedThreadPool.shutdown();

        cachedThreadPool.shutdownNow();

验证各种线程池特性:

创建执行的任务:任务就是打印各自的"类路径+@+hashcode"。

    public static class MyRunable implements Runnable {

        public MyRunable(){

        }

        @Override
        public void run() {
            System.out.println("开始处理任务");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("当前执行任务线程" + this.toString());
        }
    }

1.循环创建任务放入CachedThreadPool中执行:

        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

        for(int i=0;i<10;i++){
            cachedThreadPool.execute(new MyRunable());
        }

打印结果:给多少个任务,就创建多少个线程,缓存线程池不限制线程大小

开始处理任务
开始处理任务
开始处理任务
开始处理任务
开始处理任务
开始处理任务
开始处理任务
开始处理任务
开始处理任务
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@4ee88e47
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@51dbc572
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@6350da9f
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@34258bc7
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@2dd943ad
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@786a52e0
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@b89fbe7
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@834fe66
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@52922937
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@3d339f20

2.循环创建任务放入SingleThreadPool中执行:

        ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();

        for(int i=0;i<10;i++){
            singleThreadPool.execute(new MyRunable());
        }

当前只有一个线程处理任务,任务按照加入顺序依序执行:

开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@35b893c9
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@3b7f6b0e
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@3f40f8b9
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@7a426135
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@b95836f
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@4bf2be08
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@73cf02ff
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@1a6d9e7a
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@3d44e8a3
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@639803fd

3.循环创建任务放入FixedThreadPool中执行:
定长线程池,设置最大线程数为3;

        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        for(int i=0;i<10;i++){
            fixedThreadPool.execute(new MyRunable());
        }

最多能有3个线程同时处理任务:

开始处理任务
开始处理任务
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@f1c2027
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@464fea81
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@72e3cfe6
开始处理任务
开始处理任务
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@48881c38
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@7c242fca
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@1dbcfb4
开始处理任务
开始处理任务
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@4cb781f1
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@5e44b57
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@781ba496
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@9b51603

4.循环创建任务放入ScheduledThreadPool中执行:

        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
        for(int i=0;i<10;i++){
            scheduledExecutorService.schedule(new MyRunable(),4, TimeUnit.SECONDS);
        }

也是需要固定线程大小,不过比fixed多了延迟执行。

开始处理任务
开始处理任务
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@2fec69f9
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@1188fc84
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@7b1e0a3d
开始处理任务
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@1f4f00c5
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@75d9fb2e
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@2bd3e8dc
开始处理任务
开始处理任务
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@71e6614d
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@1b7097f4
开始处理任务
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@6ed163c2
当前执行任务线程com.example.apple.threadpooluse.MainActivity$MyRunable@34e4f115

相关文章

  • Java线程池的使用

    线程类型: 固定线程 cached线程 定时线程 固定线程池使用 cache线程池使用 定时调度线程池使用

  • java----线程池

    什么是线程池 为什么要使用线程池 线程池的处理逻辑 如何使用线程池 如何合理配置线程池的大小 结语 什么是线程池 ...

  • spring 线程池和java线程池

    jdk线程池就是使用jdk线程工具类ThreadPoolExecutor 创建线程池spring线程池就是使用自己...

  • Spring @Async开启异步任务

    定义线程池 使用线程池

  • 八、线程池剖析

    一、前置问题 线程的状态转换 为什么要使用线程池 线程池的继承体系 线程池使用的场景 线程数的设置规则 线程池的状...

  • 1203-AsyncTask详解一:线程池的基本设置

    AsyncTask的内部使用线程池处理并发,要了解它是怎样使用线程池的,那要先了解线程池的基本设置 线程池的基本参...

  • ExecutorService shutdown()和shutd

    ExecutorService是我们经常使用的线程池,当我们使用完线程池后,需要关闭线程池。ExecutorSer...

  • java 线程池使用和详解

    线程池的使用 构造方法 corePoolSize:线程池维护线程的最少数量 maximumPoolSize:线程池...

  • java线程池

    线程VS线程池 普通线程使用 创建线程池 执行任务 执行完毕,释放线程对象 线程池 创建线程池 拿线程池线程去执行...

  • Android中的线程池

    前言 提到线程池,我们先说一下使用线程池的好处。使用线程池的优点可以概括为:1、重复使用线程池中的线程,避免因为线...

网友评论

    本文标题:线程池的使用

    本文链接:https://www.haomeiwen.com/subject/rxjvxqtx.html