线程池之小结

先看两个概念:

线程:进程中负责程序执行的执行单元。一个进程中至少有一个线程。

多线程:解决多任务同时执行的需求,合理使用CPU资源。多线程的运行是根据CPU切换完成,如何切换由CPU决定,因此多线程运行具有不确定性。

线程池定义

线程池基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。

Java里面线程池的顶级接口是 Executor,不过真正的线程池接口是 ExecutorService, ExecutorService 的默认实现是 ThreadPoolExecutor;普通类 Executors 里面调用的就是 ThreadPoolExecutor。

线程池源码

public interface Executor {
    void execute(Runnable command);
}
public interface ExecutorService extends Executor {
    void shutdown();
    List<Runnable> shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);
    ...
}
public class Executors {
    public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, 
                            new SynchronousQueue<Runnable>());
    }
    ...
}

线程池的优点

  1. 避免线程的创建和销毁带来的性能开销。
  2. 避免大量的线程间因互相抢占系统资源导致的阻塞现象。
  3. 能够对线程进行简单的管理并提供定时执行、间隔执行等功能。

线程池的使用

在Java中Executors是一个关于线程池的父亲接口该类中具有多个构造方法,用来完成不同类型的线程池的创建

1、固定大小的线程池

Executors threadPool= (Executors) Executors.newFixedThreadPool(3);

固定大小的线程池当多个任务同时提交时,始终在线程池中具有一开始设置的线程数目,多余该数目的其他任务暂时阻塞在队列中等待线程池的操作。

2、具有缓冲的线程池(可变大小的线程池)

Executors threadPool= (Executors) Executors.newCachedThreadPool();

此类型线程池大小随着任务数量的多少,进行浮动的线程数创建,线程池中的线程数是浮动的。

3、单个线程的线程池

Executors threadPool=Executors.newSingleThreadExecutor();

此类线程池中的线程数始终只有一个,并且不会增多或者减少。

比较 单个线程的线程池和单独一个线程

  • 单个线程的线程池,当该线程被关闭之后,线程池自动会生成一个新的线程来维持线程池中始终有一个线程;
  • 在运行的职责,类似线程被重新启动了,但是线程不再是之前的那个线程,因为线程号已经变化;
  • 单独一个线程,当该线程被关闭之后就关闭了,没有重新启动。

Android中的线程池

在Android中使用的线程池是ThreadPoolExecutor

ThreadPoolExecutor threadPoolExecutor= new ThreadPoolExecutor(int corePoolSize, int maxinumPoolSize, long keepAliveTime, TimeUnit unit, BlockingDeque<Runnable> workQueue, ThreadFactory threadFactory);

各参数含义:

  • int corePoolSize : 线程池中的核心线程数
  • int maxinumPoolSize :线程池中允许的最大线程数目
  • long keepAliveTime :非核心线程的超时时间,超出这个时间非核心线程会被回收
  • TimeUnit unit :非核心线程的超时时间的时间单位
  • BlockingDeque workQueue : 保存需要线程池执行的任务的列表
  • ThreadFactory threadFactory : 线程工厂,只是一个接口,只有一个方法Thread newThread(Runnable r)

使用示例:

public class MyThreadFactory {
    //Android的线程池类
    private static ThreadPoolExecutor threadPoolExecutor=null;
    //获取当前用户的手机的CPU的核心数
    private static int num=Runtime.getRuntime().availableProcessors();
    //用于存储提交任务的任务队列
    private static BlockingDeque<Runnable> workQueue=new LinkedBlockingDeque<>(num*50);
    private MyThreadFactory(){
    }
    public static ThreadPoolExecutor getThreadPoolExecutor(){
        if(null==threadPoolExecutor){
            threadPoolExecutor=new ThreadPoolExecutor(num*2, num*4, 8, TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.CallerRunsPolicy());
//            threadPoolExecutor=new ThreadPoolExecutor(1, 1, 8, TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.CallerRunsPolicy());
        }
        return threadPoolExecutor;
    }
}

原文发布于微信公众号 - Android机动车(JsAndroidClub)

原文发表时间:2017-12-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏互扯程序

Java线程池使用说明

现在是资源共享的时代,同样也是知识分享的时代,如果你觉得本文能学到知识,请把知识与别人分享。

14820
来自专栏LuckQI

学习Java基础知识,打通面试关~十五线程池学习

9530
来自专栏编程

浅析Windows下堆的结构

*本文原创作者:hellowuzekai,本文属FreeBuf原创奖励计划,未经许可禁止转载 简介 Windows下的堆主要有两种,进程的默认堆和自己创建的私有...

296100
来自专栏Java 源码分析

Exectors框架 源码分析

Exectors框架 源码分析 1. 在阅读源码时做了大量的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限,并且代码阅读起来没有 IDE 方便,...

28970
来自专栏听Allen瞎扯淡

CompletionService小技巧

在上一篇blogs中,我详细的解释了CompletionService的使用方法和ExecutorCompletionService的详细实现,这篇blogs中...

22230
来自专栏Java 源码分析

Exectors框架 源码分析

Exectors框架 源码分析 1. 在阅读源码时做了大量的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限,并且代码阅读起来没有 IDE 方便,...

27360
来自专栏JMCui

多线程编程学习五(线程池的创建)

一、概述 New Thread的弊端如下:        a、每次New Thread新建对象性能差。        b、线程缺乏统一的管理,可能无限制的新建...

411110
来自专栏Java3y

线程池你真不来了解一下吗?

26260
来自专栏cmazxiaoma的架构师之路

通过了解RejectedExecutionException来分析ThreadPoolExecutor源码

观看本文章之前,最好看一下这篇文章熟悉下ThreadPoolExecutor基础知识。 1.关于Java多线程的一些常考知识点 2.看ThreadPoolE...

17320
来自专栏FreeBuf

浅析Windows下堆的结构

简介 Windows下的堆主要有两种,进程的默认堆和自己创建的私有堆。在程序启动时,系统在刚刚创建的进程虚拟地址空间中创建一个进程的默认堆,而且程序也可以通过 ...

24680

扫码关注云+社区

领取腾讯云代金券