Android中的线程和线程池的使用及封装使用总结

相关线程知识先扩充一下:
主线程和子线程
主线程(也叫UI线程):在java中默认情况下一个进程只有一个线程,这个线程就是主线程。其主要作用是处理和界面交互相关的逻辑,主线程不能做太多耗时的操作,否则会产生界面卡顿的感觉。为保持较快的响应速度,子线程就出场了。
子线程:也叫工作线程,除了主线程之外的都是子线程。

基本用途:主线程是运行四大组件及处理它们和用户的交互,子线程处理耗时的任务,如网络请求、I/O操作等。

Android中的线程表现形式:
Thread、AsyncTask、HanderThread、IntentService.

简单介绍一下后三者的注意事项
1.AysncTask: 可理解为轻量级的线程池,异步任务类,其封装了Thread和Handler,通过AysncTask可以很方便的执行后台任务及在主线程中访问UI.
缺点:不适合进行特别耗时的后台任务,对于特别耗时的任务最好用池线程池替换。
2.HandlerThread: 继承自Thread,它是一种可以 使用Handler和Thread.实现也很简单,在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环。
3.IntentService: 继承自Service,是一个抽象类,所以必须创建他的子类才能使用IntentSerivce,可用于执行后台耗时任务,当任务完成后会自动停止,该优先级高于其他单纯的线程,不容易补系统杀死。 IntentSerivce 封装了Handler和HandlerThread.

线程池的好处:

1.Android中像访问内存卡,联网等耗时较长的任务时,需要在异步线程中进行,所以需要新开线程进行。但创建或者销毁线程伴随着系统的开销,频繁的创建和销毁线程,会较大的影响系统的性能。使用线程池,可用已有的闲置线程来执行新任务。

2.我们知道线程能共享系统资源,如果同时执行的线程过多,就有可能导致系统资源不足而产生阻塞的情况,运用线程池能有效的控制线程最大并发数(maximumPoolSize),避免以上的问题。
3.线程池能够对线程进行有效的管理,比如延时执行,定时定周期循环执行等。

Android中的线程池来源于java,主要是通过Executor 来派生特定类型的线程池,不同类型的线程池有不同的意义。Executor是一个接口,真正地实现为ThreadPoolExecutor,他提供了一系列的参数来配置线程池。不同参数意味着不同的线程池。

最后该介绍一下主角线程池了。它分为四种:
FixedThreadPool
特点:
①可控制线程最大并发数(线程数固定)
②超出的线程会在队列中等待
使用优势:能够更快的响应外界的请求。

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

}

CachedThreadPool
缓存线程池的特点:
① 线程数无限制
② 没有核心线程,都是非核心线程
优势:比较适合用来执行大量的但是耗时较少的任务。

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

ScheduledThreadPool
使用场景:用于执行定时任务和具有固定周期的重复任务。
SingleTreadExecutor
使用场景:按顺序执行,不需要处理同步的问题。

据此 四种线程池简单介绍完成,下面介绍下如何封装使用线程池。

/**
 * 线程池封装
 *
 * @author jun.yang
 *         created at 2018/2/26 10:21
 */
public class ThreadPoolManager {
    private static ThreadPoolManager mInstance;

public static ThreadPoolManager getInstance() {
    if (mInstance == null) {
        synchronized (ThreadPoolManager.class) {
            if (mInstance == null) {
                mInstance = new ThreadPoolManager();
            }
        }
    }
    return mInstance;
}


/**
 * 核心线程池的数量,同时能够执行的线程数量
 */
private int corePoolSize;
/**
 * 最大线程池数量,表示当缓冲队列满的时候能继续容纳的等待任务的数量
 */
private int maximumPoolSize;
/**
 * 存活时间
 */
private long keepAliveTime = 1;
private TimeUnit unit = TimeUnit.HOURS;
private ThreadPoolExecutor executor;

private ThreadPoolManager() {
    /**
     * 给corePoolSize赋值:当前设备可用处理器核心数*2 + 1,能够让cpu的效率得到最大程度执行(有研究论证的)
     */
    corePoolSize = Runtime.getRuntime().availableProcessors() * 2 + 1;
    //虽然maximumPoolSize用不到,但是需要赋值,否则报错
    maximumPoolSize = corePoolSize;
    executor = new ThreadPoolExecutor(
            //当某个核心任务执行完毕,会依次从缓冲队列中取出等待任务
            corePoolSize,
            //5,先corePoolSize,然后new LinkedBlockingQueue<Runnable>(),然后maximumPoolSize,但是它的数量是包含了corePoolSize的
            maximumPoolSize,
            //表示的是maximumPoolSize当中等待任务的存活时间
            keepAliveTime,
            unit,
            //缓冲队列,用于存放等待任务,Linked的先进先出
            new LinkedBlockingQueue<Runnable>(),
            //创建线程的工厂
        //  Executors.defaultThreadFactory(),
            new DefaultThreadFactory(Thread.NORM_PRIORITY, "tiaoba-pool-"),
            //用来对超出maximumPoolSize的任务的处理策略
            new ThreadPoolExecutor.AbortPolicy()
    );
}

/**
 * 执行任务
 *
 * @param runnable
 */
public void execute(Runnable runnable) {
    if (executor == null) {
        //线程池执行者。
        //参1:核心线程数;参2:最大线程数;参3:线程休眠时间;参4:时间单位;参5:线程队列;参6:生产线程的工厂;参7:线程异常处理策略
        executor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(),
            //   Executors.defaultThreadFactory(),
                new DefaultThreadFactory(Thread.NORM_PRIORITY, "tiaoba-pool-"),
                new ThreadPoolExecutor.AbortPolicy());
    }
    if (runnable != null) {
        executor.execute(runnable);
    }
}

/**
 * 移除任务
 */
public void remove(Runnable runnable) {
    if (runnable != null) {
        executor.remove(runnable);
    }
}

/**
 * 创建线程的工厂,设置线程的优先级,group,以及命名
 */
private static class DefaultThreadFactory implements ThreadFactory {
    /**
     * 线程池的计数
     */
    private static final AtomicInteger poolNumber = new AtomicInteger(1);

    /**
     * 线程的计数
     */
    private final AtomicInteger threadNumber = new AtomicInteger(1);

    private final ThreadGroup group;
    private final String namePrefix;
    private final int threadPriority;

    DefaultThreadFactory(int threadPriority, String threadNamePrefix) {
        this.threadPriority = threadPriority;
        this.group = Thread.currentThread().getThreadGroup();
        namePrefix = threadNamePrefix + poolNumber.getAndIncrement() + "-thread-";
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
        if (t.isDaemon()) {
            t.setDaemon(false);
        }
        t.setPriority(threadPriority);
        return t;
    }
   }
  }

调用方法:

ThreadPoolManager.getInstance().execute(command));

Runnable command =  new Runnable(){
    @Override
    public void run(){
    SystemClock.sleep(2000)
    }
}

猜你喜欢

转载自blog.csdn.net/jun5753/article/details/79521635