1、线程
注意线程是可以设置优先级的
new Thread(new Runnable() {
@Override
public void run() {
//设置线程优先级,减少与UI线程的竞争
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
}
}).start();
特定场景下(例如App启动阶段为避免在主线程创建线程池的资源消耗)使用的话务必加上优先级的设置,而且在启动阶段这样创建线程的开销要小于创建线程池的开销
2、正确使用AsyncTask
可以方便的进行线程切换,并且线程的优先级已经被默认设置成了:THREAD_PRIORITY_BACKGROUND,不会与UI线程抢占资源
AsyncTask中的任务默认是放入ArrayDeque中,串行执行,正确使用AsyncTask的串行与并行
3、线程池的使用
package com.miduo.glidestudy;
import android.os.Process;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadManager {
private static ThreadPoolProxy mShortPool = null;
private static Object mShortLock = new Object();
public static void execute(final ThreadRunnable runnable)
{
getShortPool().execute(new Runnable() {
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
runnable.doInBackGround();
}
});
}
abstract static class ThreadRunnable{
abstract void doInBackGround();
}
/** 获取一个用于执行短耗时任务的线程池,避免因为和耗时长的任务处在同一个队列而长时间得不到执行,通常用来执行本地的IO/SQL */
public static ThreadPoolProxy getShortPool() {
synchronized (mShortLock) {
if (mShortPool == null) {
mShortPool = new ThreadPoolProxy(2, 2, 5L);
}
return mShortPool;
}
}
public static class ThreadPoolProxy {
private ThreadPoolExecutor mPool;
private int mCorePoolSize;
private int mMaximumPoolSize;
private long mKeepAliveTime;
private ThreadPoolProxy(int corePoolSize, int maximumPoolSize, long keepAliveTime) {
mCorePoolSize = corePoolSize;
mMaximumPoolSize = maximumPoolSize;
mKeepAliveTime = keepAliveTime;
}
/** 执行任务,当线程池处于关闭,将会重新创建新的线程池 */
public synchronized void execute(Runnable run) {
if (run == null) {
return;
}
if (mPool == null || mPool.isShutdown()) {
//参数说明
//当线程池中的线程小于mCorePoolSize,直接创建新的线程加入线程池执行任务
//当线程池中的线程数目等于mCorePoolSize,将会把任务放入任务队列BlockingQueue中
//当BlockingQueue中的任务放满了,将会创建新的线程去执行,
//但是当总线程数大于mMaximumPoolSize时,将会抛出异常,交给RejectedExecutionHandler处理
//mKeepAliveTime是线程执行完任务后,且队列中没有可以执行的任务,存活的时间,后面的参数是时间单位
//ThreadFactory是每次创建新的线程工厂
mPool = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, mKeepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
}
mPool.execute(run);
}
/** 取消线程池中某个还未执行的任务 */
public synchronized void cancel(Runnable run) {
if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {//(线程池没有关闭或者说正在关闭,但还没有完全关闭)
mPool.getQueue().remove(run);
}
}
/** 判断线程池中是否包含指定的任务 */
public synchronized boolean contains(Runnable run) {
if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
return mPool.getQueue().contains(run);
} else {
return false;
}
}
/** 立刻关闭线程池,并且正在执行的任务也将会被中断 */
public void stop() {
if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
mPool.shutdownNow();
}
}
/** 平缓关闭单任务线程池,但是会确保所有已经加入的任务都将会被执行完毕才关闭 */
public synchronized void shutdown() {
if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
mPool.shutdown();
}
}
}
}
线程的优先级具有继承性,在某线程中创建的线程会继承此线程的优先级。那么我们在UI线程中创建了线程池,其中的线程优先级是和UI线程优先级一样的;所以仍然可能出现20个同样优先级的线程平等的和UI线程抢占资源
在上面的示例中,我们设置了线程池中的线程的优先级为
THREAD_PRIORITY_BACKGROUND,AsyncTask就是这么用的