異步任務(wù)AsyncTask 源碼 地址http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/os/AsyncTask.java
最近在Android開發(fā)上遇到線程遇到諸多問題吃嘿,特此記錄下嚎卫。也希望能為諸君貢獻(xiàn)一二嫌拣。
Code一版
直接使用new Thread
new Thread(new Runnable() {
@Override
public void run() {
doSomething();//執(zhí)行代碼(耗時(shí)等 數(shù)據(jù)庫操作等)
}
}).start();
很明顯的弊端,Code中太多地方需要線程的地方锚赤,new 了無數(shù)個(gè)線程。
1.每次new Thread新建對象性能差
2. 線程缺乏統(tǒng)一管理调违,可能無限制新建線程汽烦,相互之間競爭,即可能占用過多的系統(tǒng)資源導(dǎo)致死機(jī)
3.缺乏更多功能屹篓,比如定時(shí)執(zhí)行疙渣,定期執(zhí)行,線程中斷堆巧。
總之最后很扎心妄荔,而且你能想象這放在一個(gè)性能很差的Android機(jī)里面運(yùn)行么~~
Code二版
使用定義的線程池
先來個(gè)我定義的
/**
* 線程池管理(線程統(tǒng)一調(diào)度管理)
*/
public final class ThreadPoolManager {
public static class ThreadPoolProxy {
ThreadPoolExecutor mExecutor;
private int mCorePoolSize;
private int mMaximumPoolSize;
/**
* @param corePoolSize 核心池的大小
* @param maximumPoolSize 最大線程數(shù)
*/
public ThreadPoolProxy(int corePoolSize, int maximumPoolSize) {
mCorePoolSize = corePoolSize;
mMaximumPoolSize = maximumPoolSize;
}
/**
* 初始化ThreadPoolExecutor
* 雙重檢查加鎖,只有在第一次實(shí)例化的時(shí)候才啟用同步機(jī)制,提高了性能
*/
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);
}
}
}
}
/**
執(zhí)行任務(wù)和提交任務(wù)的區(qū)別?
1.有無返回值
execute->沒有返回值
submit-->有返回值
2.Future的具體作用?
1.有方法可以接收一個(gè)任務(wù)執(zhí)行完成之后的結(jié)果,其實(shí)就是get方法,get方法是一個(gè)阻塞方法
2.get方法的簽名拋出了異常===>可以處理任務(wù)執(zhí)行過程中可能遇到的異常
*/
/**
* 執(zhí)行任務(wù)
*/
public void execute(Runnable task) {
initThreadPoolExecutor();
mExecutor.execute(task);
}
/**
* 提交任務(wù)
*/
public Future submit(Runnable task) {
initThreadPoolExecutor();
return mExecutor.submit(task);
}
/**
* 移除任務(wù)
*/
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三版
手動控制版線程池(將所有事務(wù)分類放在規(guī)定的線程中執(zhí)行,(未不同類別的事務(wù)規(guī)定不同的線程))
/**
* 本地?cái)?shù)據(jù)處理和耗時(shí)處理用不同線程處理
*/
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;
/**
* 發(fā)消息
* @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兩種方式 區(qū)別
2方式一旦有線程操作失誤可能會導(dǎo)致全線線程癱瘓,導(dǎo)致整個(gè)線程池?zé)o法正常的運(yùn)行下去航背,
3方式使用失誤 基本只會導(dǎo)致其一線程癱瘓玖媚,更易于查找 修復(fù)今魔。