异步任务AsyncTask 源码 地址http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/os/AsyncTask.java
最近在Android开发上遇到线程遇到诸多问题,特此记录下。也希望能为诸君贡献一二。
Code一版
直接使用new Thread
new Thread(new Runnable() {
@Override
public void run() {
doSomething();//执行代码(耗时等 数据库操作等)
}
}).start();
很明显的弊端,Code中太多地方需要线程的地方,new 了无数个线程。
1.每次new Thread新建对象性能差
2. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,即可能占用过多的系统资源导致死机
3.缺乏更多功能,比如定时执行,定期执行,线程中断。
总之最后很扎心,而且你能想象这放在一个性能很差的Android机里面运行么~~
Code二版
使用定义的线程池
先来个我定义的
/**
* 线程池管理(线程统一调度管理)
*/
public final class ThreadPoolManager {
public static class ThreadPoolProxy {
ThreadPoolExecutor mExecutor;
private int mCorePoolSize;
private int mMaximumPoolSize;
/**
* @param corePoolSize 核心池的大小
* @param maximumPoolSize 最大线程数
*/
public ThreadPoolProxy(int corePoolSize, int maximumPoolSize) {
mCorePoolSize = corePoolSize;
mMaximumPoolSize = maximumPoolSize;
}
/**
* 初始化ThreadPoolExecutor
* 双重检查加锁,只有在第一次实例化的时候才启用同步机制,提高了性能
*/
private void initThreadPoolExecutor() {
if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
synchronized (ThreadPoolProxy.class) {
if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
long keepAliveTime = 3000;
TimeUnit unit = TimeUnit.MILLISECONDS;
BlockingQueue workQueue = new LinkedBlockingDeque<>();
ThreadFactory threadFactory = Executors.defaultThreadFactory();
RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
mExecutor = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, handler);
}
}
}
}
/**
执行任务和提交任务的区别?
1.有无返回值
execute->没有返回值
submit-->有返回值
2.Future的具体作用?
1.有方法可以接收一个任务执行完成之后的结果,其实就是get方法,get方法是一个阻塞方法
2.get方法的签名抛出了异常===>可以处理任务执行过程中可能遇到的异常
*/
/**
* 执行任务
*/
public void execute(Runnable task) {
initThreadPoolExecutor();
mExecutor.execute(task);
}
/**
* 提交任务
*/
public Future submit(Runnable task) {
initThreadPoolExecutor();
return mExecutor.submit(task);
}
/**
* 移除任务
*/
public void remove(Runnable task) {
initThreadPoolExecutor();
mExecutor.remove(task);
}
}
/**
* 线程池工厂类
* Created by Samson on 2018/2/11.
* 使用方法
* ThreadPoolProxyFactory .getNormalThreadPoolProxy().execute(Runnable);
*/
public static class ThreadPoolProxyFactory {
private static ThreadPoolProxy mNormalThreadPoolProxy;
private static ThreadPoolProxy mDownLoadThreadPoolProxy;
/**
* 得到普通线程池代理对象mNormalThreadPoolProxy
*/
public static ThreadPoolProxy getNormalThreadPoolProxy() {
if (mNormalThreadPoolProxy == null) {
synchronized (ThreadPoolProxyFactory.class) {
if (mNormalThreadPoolProxy == null) {
mNormalThreadPoolProxy = new ThreadPoolProxy(10 , 10);
}
}
}
return mNormalThreadPoolProxy;
}
/**
* 下载专用
* 得到下载线程池代理对象mDownLoadThreadPoolProxy
*/
public static ThreadPoolProxy getDownLoadThreadPoolProxy() {
if (mDownLoadThreadPoolProxy == null) {
synchronized (ThreadPoolProxyFactory.class) {
if (mDownLoadThreadPoolProxy == null) {
mDownLoadThreadPoolProxy = new ThreadPoolProxy(3, 3);
}
}
}
return mDownLoadThreadPoolProxy;
}
}
}
如何使用:
ThreadPoolManager.ThreadPoolProxyFactory.getNormalThreadPoolProxy()
.execute(new Runnable() {
@Override
public void run() {
doSomething();
}
});
-----------------------------------------lambda
ThreadPoolManager.ThreadPoolProxyFactory.getNormalThreadPoolProxy()
.execute(() -> {doSomething();});
Code三版
手动控制版线程池(将所有事务分类放在规定的线程中执行,(未不同类别的事务规定不同的线程))
/**
* 本地数据处理和耗时处理用不同线程处理
*/
public class ThreadPoolUtil {
private List<Run> runList = new ArrayList<>();
private List<Run> runListTemp = new ArrayList<>();
private Thread thread = null;
public interface Run {
void run();
}
private ThreadPoolUtil() {
init();
}
private void init() {
if (thread == null) {
thread = new Thread(() -> {
for (; ; ) {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
dealRun();
}
});
thread.start();
}
}
private final Object lock = new Object();
private static ThreadPoolUtil _INSTANCESEND = null;
private static ThreadPoolUtil _INSTANCESERVER = null;
private static ThreadPoolUtil _INSTANCENORMAL = null;
/**
* 发消息
* @return
*/
public static ThreadPoolUtil getSendMsgInstance() {
if (_INSTANCESEND == null) {
_INSTANCESEND = new ThreadPoolUtil();
}
return _INSTANCESEND;
}
/**
* 收消息
* @return
*/
public static ThreadPoolUtil getGetMsgInstance() {
if (_INSTANCESERVER == null) {
_INSTANCESERVER = new ThreadPoolUtil();
}
return _INSTANCESERVER;
}
/**
* 普通通用消息
* @return
*/
public static ThreadPoolUtil getNormalInstance() {
if (_INSTANCENORMAL == null) {
_INSTANCENORMAL = new ThreadPoolUtil();
}
return _INSTANCENORMAL;
}
public void addRun(Run run) {
runListTemp.add(run);
synchronized (lock) {
runList.addAll(runListTemp);
runListTemp.clear();
lock.notify();
}
}
private Run getRun() {
if (runList.size() <= 0) {
return null;
}
Run run = null;
synchronized (lock) {
run = runList.get(0);
runList.remove(0);
}
return run;
}
private void dealRun() {
try {
for (Run run = getRun(); (run) != null; ) {
run.run();
run = getRun();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
如何使用:不同的分类可 get 不同的线程来处理。
ThreadPoolUtil.getNormalInstance().addRun(new ThreadPoolUtil.Run() {
@Override
public void run() {
doSomething();
}
});
-----------------------------------------lambda
ThreadPoolUtil.getNormalInstance().addRun(() ->{
doSomething();
});
2,3两种方式 区别
2方式一旦有线程操作失误可能会导致全线线程瘫痪,导致整个线程池无法正常的运行下去,
3方式使用失误 基本只会导致其一线程瘫痪,更易于查找 修复。