美文网首页
线程和线程池

线程和线程池

作者: 玄策 | 来源:发表于2017-08-04 17:26 被阅读6次

参考资料

Java多线程问题总结


目录

  • 1)主线程和子线程
  • 2)线程形态
    • 2.1)AsyncTask
    • 2.2)HandlerThread
    • 2.3)IntentService
  • 3)线程池
    • 3.1)ThreadPoolExecutor
    • 3.2)线程池的分类

1)主线程和子线程


2)线程形态

2.1)AsyncTask

封装了线程池和Handler,主要方便在子线程中更新UI。

//Params 参数类型
//Progress 后台任务执行进度的类型
//Result 后台任务返回结果的类型
public abstract class AsyncTask<Params,Progress,Result>

//四个方法
//在主线程中执行,异步任务执行前,此方法被调用
onPreExecute()

//线程池中执行
doInBackground(Params...params){
  //更新进度,会调用onProgressUpdate()
  publicProgress(values);
}

//异步任务取消时被调用
onCancelled() 

//主线程中执行,执行进度发生改变调用
onProgressUpdate(Progress...values)

//主线程中执行,异步任务结束后会调用
onPostExecute(Result result)

注意:

  • AsyncTask的实例必须在UI thread中创建;
  • execute方法必须在UI thread中调用;
  • 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
  • 一个AsyncTask只能被执行一次,即execute()只能被调用一次,否则多次调用时将会出现异常;
//AsyncTask从Android3.0开始,默认情况下是串行执行的。为了让其在Android3.0及以上版本并行执行,可以采用
new mAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"");

AsyncTask中有两个线程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一个Handler(InternalHandler),
SerialExecutor用于任务排队,而THREAD_POOL_EXECUTOR用于执行任务,InternalHandler则是将执行环境从线程池切换到主线程。


2.2)HandlerThread

HandlerThread继承了Thread,是一种可以使用Handler的Thread,其实它就是在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环。它有个具体使用场景,就是IntentService。
示例1:

// Step 1: 创建并启动HandlerThread线程,内部包含Looper
HandlerThread handlerThread = new HandlerThread("tgf");
handlerThread.start();

// Step 2: 创建Handler
Handler handler = new Handler(handlerThread.getLooper());

// Step 3: 发送消息
handler.post(new Runnable() {

        @Override
        public void run() {
            System.out.println("thread id="+Thread.currentThread().getId());
        }
    });

示例2:

class LooperThread extends Thread {
    public Handler mHandler;

    public void run() {
        Looper.prepare();
        // Step 1: 创建Handler
        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                //TODO 处理即将发送过来的消息
            }
        };

        Looper.loop();
    }
}

// Step 2: 创建并启动LooperThread线程,内部包含Looper
LooperThread looperThread = new LooperThread("tgf");
looperThread.start();

// Step 3: 发送消息
looperThread.mHandler.sendEmptyMessage(10);

2.3)IntentService

https://mp.weixin.qq.com/s?__biz=MzI0MjE3OTYwMg==&mid=401611665&idx=1&sn=9b6b1f2924d4adfe4e89a322ab53df9c&scene=21#wechat_redirect
IntentService是一个服务,内部采用HandlerThread来执行任务,HandlerThread是一个工作线程(子线程),其Handler的handleMessage会回调onHandleIntent并stopSelf,执行完毕自动退出。很像是一个后台线程,但却是一个服务,所以不容易被系统杀死。

  • 多次startService(Intent intent)会串行执行onHandleIntent()
  • 只能startService启动,源码中onBind => return null;
@override
protected void onHandleIntent(Intent intent)

3)线程池

线程是操作系统调度的最小单元,它的创建和销毁都有相应的开销,当系统中存在大量线程时,系统会通过时间片轮转的方式调度。频繁的创建和销毁线程并不高效。正确的方式是采用线程池,一个线程池中缓存一定数量线程,减小开销。

线程池优点
避免重复创建销毁的开销
控制最大并发,避免大量线程争抢资源
有效的管理,如可以定时或指定间隔循环执行等

Java的线程池来源于Executor接口,真正实现为ThreadPoolExecutor

3.1)ThreadPoolExecutor

//corePoolSize 核心线程数,默认核心线程会在线程池内一直存活,除非设定allowCoreThreadTimeOut=true。
//maximumPoolSize 最大线程数,活动线程达到此峰值,后续任务将被阻塞
//keepAliveTime 非核心线程超时时间,超过则被回收
//unit keepAliveTime的时间单位,枚举TimeUnit.MILLSECONDS(毫秒), TimeUnit.SECONDS(秒)等。
//workQueue 任务队列,提交的任务runnable对象被存储在这
//threadFactory 线程工厂,为线程池创建新线程。
public ThreadPoolExecutor(
  int corePoolSize,
  int maximumPoolSize,
  long keepAliveTime,
  TimeUnit unit,
  BlockingQueue<Runnable> workQueue,
  ThreadFactory threadFactory
)
ThreadPoolExecutor执行任务的规则
当前线程数量<核心线程数,启动一个核心线程执行任务
当前线程数量>=核心线程数,将任务插入任务队列排队
任务队列满了,当前线程数<最大线程数,启动非核心线程执行任务
任务队列满了,当前线程数>=最大线程数,拒绝此任务

3.2)线程池的分类

分类 说明
FixedThreadPool 只有数量固定核心线程,无超时。所以能快速响应
CachedThreadPool 只有非核心线程,最大数量Integer.MAX_VALUE,空闲60秒后回收,适合大数量但耗时少任务
ScheduledThreadPool 核心线程数量固定,非核心线程数无限制,非核心闲置会立即回收,适合定时任务或固定周期重复任务
SingleThreadPool 只有一个核心线程,适合处理线程同步
  • FixedThreadPool
//调用
ExecutorService a = Executor.newFixedThreadPool(4);
a.execute(runnable);
//源码
public static ExecutorService newFixedThreadPool(int nThreads){
  return new ThreadPoolExecutor(
    nThreads,
    nThreads,
    0L,
    TimeUnit.MILLSECONDS,
    new LinkedBlockingQueue<Runnable>()
  );
}

*CachedThreadPool

ExecutorService a = Executor.newCachedThreadPool();
a.execute(runnable);
public static ExecutorService newCachedThreadPool(){
  return new ThreadExecutor(
    0,
    Integer.MAX_VALUE,
    60L,
    TimeUnit.SECONDS,
    new SynchronousQueue<Runnable>()
  );
} 
  • ScheduledThreadPool
ScheduledExecutorService a = Executor.newScheduledThreadPool(4);
//2000ms后执行runnable
a.schedule(runnable,2000,TimeUnit.MILLSECONDS);
//延迟10ms后,每隔1000ms执行一次runnable
a.scheduleAtFixedRate(runnable,10,1000,TimeUnit.MILLSECONDS);
public static ScheduledExecutor newScheduledThreadPool(int corePoolSize){
  return new ScheduledThreadPoolExecutor(corePoolSize);
} 

public ScheduledThreadPoolExecutor(int corePoolSize){
  super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,new DelayedWorkQueue());
}
  • SingleThreadPool
ExecutorService a = Executor.newSingleThreadExecutor();
a.execute(runnable);
public static ExecutorService newSingleThreadExecutor(){
  return new FinalizableDelegatedExecutorService(
    new ThreadPoolExecutor(
      1,1,0L,TimeUnit.MILLSECONDS,
      new LinkedBlockingQueue<Runnable>()
    )
  );
} 

相关文章

  • Springboot | 线程池的学习,多线程池配置示例

    一、线程和进程,线程的生命周期二、单线程和多线程三、线程池的概念四、线程池的使用五、多线程池配置示例 一、线程和进...

  • 线程池查漏补缺

    tomcat线程池和jdk线程池区别 概述 线程池是什么,为什么要线程池 jdk有哪些线程池和原理 第三方中间件的...

  • 线程池概述

    为什么要使用线程池? 线程池核心参数 线程池的几种拒绝策略 execute()和submit()的区别 线程池工作...

  • java线程池

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

  • 第九章 线程池

    线程池的实现原理和使用建议。 当提交一个新任务到线程池时,线程池的处理流程如下。1)线程池判断核心线程池里的线程是...

  • 我们的线程被饿死了

    我们的线程被饿死了 我们在构建线程池的时候可以构建单个线程的线程池和多个线程的线程池。 那么线程池使用不当可不可能...

  • Android线程池的使用

    一、线程与线程池,为什么要使用线程池 1、Android中的线程 在Android中有主线程和子线程的区分。主线程...

  • Java线程池的使用

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

  • Android面试Java基础篇(二)

    (一)问:Java线程池的实现原理和使用 线程池即存放和管理线程的一个池子 (1)复用线程池中的线程,避免因为线程...

  • java----线程池

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

网友评论

      本文标题:线程和线程池

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