线程池实现方式解析

使用场景:多线程一直是一个程序健壮性的基础条件,在实现复杂业务逻辑的时候往往需要使用多线程来完成业务逻辑操作。然而线程的创建与销毁是一个耗时操作,如果在程序中反复创建和销毁线程,将会对程序的反应速度造成严重影响,有时甚至会Crash掉程序。因此在需要平凡使用线程的业务场景中,使用线程池是一个不错的选择。

本文将为大家介绍Android线程池的实现方式。在Android中实现线程池,首先需要实现一个线程工厂(ThreadFactory)的子类,具体实现方式如下所示(PriorityThreadFactory.java):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import android.os.Process;

/**
* A thread factory that create threads with a given thread priority
* @author jony
* @version 1.0
*/
public class PriorityThreadFactory implements ThreadFactory{
private final String mName;
private final int mPriority;
private final AtomicInteger mNumber = new AtomicInteger();

public PriorityThreadFactory(String name, int priority) {
mName = name;// 线程池的名称
mPriority = priority;//线程池的优先级
}
@Override
public Thread newThread(Runnable r) {
return new Thread(r, mName +"-"+mNumber.getAndIncrement()){
@Override
public void run() {
// 设置线程的优先级
Process.setThreadPriority(mPriority);
super.run();
}
};
}
}

以上是创建线程池的一个工具类,接下来为大家介绍本篇文章的重点,线程池的实现方式,具体实现方式如下所示(MyThreadPool.java):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.tcl.actionbar;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
package com.tcl.actionbar;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ThreadFactory;

// 线程池的实现方式
public class MyThreadPool {
private final static int POOL_SIZE = 4;// 线程池的大小最好设置成为CUP核数的2N
private final static int MAX_POOL_SIZE = 6;// 设置线程池的最大线程数
private final static int KEEP_ALIVE_TIME = 4;// 设置线程的存活时间
private final Executor mExecutor;
public MyThreadPool() {
// 创建线程池工厂
ThreadFactory factory = new PriorityThreadFactory("thread-pool", android.os.Process.THREAD_PRIORITY_BACKGROUND);
// 创建工作队列
BlockingQueue<Runnable> workQueue = new LinkedBlockingDeque<Runnable>();
mExecutor = new ThreadPoolExecutor(POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, workQueue, factory);
}
// 在线程池中执行线程
public void submit(Runnable command){
mExecutor.execute(command);
}
}

代码中的注释已经详细讲解了线程池的实现方式,在此不再傲述。
如果大家仔细研究代码的话,就会发现一个问题,只要创建了线程池,只要程序已启动,使用线程池的时候,线程池就会立即创建设定的线程最小个数,这样的话就会导致线程池的惊群现象(如果的我的业务逻辑现在只使用一个线程,那么其他线程资源就会白白浪费)。

使用Android系统创建的线程池,线程的数目不会因为线程的使用数目减少,而将线程池的整体数目减少。也就是说只要线程池一旦创建,线程池中线程的最小数目就是我们创建线程池时设置的最小数目。这样会导致两个问题:

一是线程池惊群现象;二是CUP资源浪费;

针对以上问题,我的解决方案是透彻分析业务逻辑,设定合理的线程数目。对于线程池的惊群现象,目前还没有很好的解决方案……

如果大家有更好解决以上两个问题的方法,欢迎大家留言,共同探讨!