关于Android中使用线程池对性能的优化以及线程池的原理,作用能理论,这里有一篇文章说得很透彻:
ExecutorService实现 线程池及使用Runnable的Queue(建议在阅读本文之前先阅读上面文章补一下理论知识,老司机可忽略本提示~~~)。
1. 执行多个AsyncTask
首先, Executors工厂类提供了五种功能不同的线程池,在附件demo的ExcutorTask类的构造方法中,分别创建了这相应的对象:
public ExcutorTask() {
// 每次只执行一条任务的线程池
singleTaskService = Executors.newSingleThreadExecutor();
// 每次执行限定个数任务的线程池
limitedTaskService = Executors.newFixedThreadPool(3);
// 根据实际情况调整线程池中线程的数量的线程池
allTaskService = Executors.newCachedThreadPool();
// 指定时间里执行任务的线程池,可重复使用
scheduledTaskService = Executors.newScheduledThreadPool(3);
// 返回一个可以控制线程池内线程定时或周期性执行某任务的线程池。只不过和上面的区别是该线程池大小为1
singleScheduledTaskService = Executors.newSingleThreadScheduledExecutor();
}
另外,该类提供了可以获取当前线程池的方法,线程池类型可以通过调用setServiceType(SERVICE_TYPE type)方法进行修改。
public ExecutorService getExecutor() {
if (mExecutor != null)
return mExecutor;
ExecutorService executor = limitedTaskService;
switch (type) {
case SINGLE:
executor = singleTaskService;
break;
case LIMITED:
executor = limitedTaskService;
break;
case ALL:
executor = allTaskService;
break;
case SCHEDULED:
executor = scheduledTaskService;
break;
case SINGLE_SCHEDULED:
executor = singleScheduledTaskService;
default:
break;
}
return executor;
}
AsyTaskItem asyitem = new AsyTaskItem(item, position);
//添加任务
asyitem.executeOnExecutor(task.getExecutor());
list.add(asyitem);
运行效果如下图所示,实例中每次执行3个任务,执行完成以后,会继续执行下面的任务。
2.异步加载多张图片
该功能的实现封装在AsyncImageLoader中
private ExecutorService executorService = Executors.newFixedThreadPool(3);
public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
public void loadImage(final String url, final ImageCallback callback, final ImageView imageView) {
if (imageCache.containsKey(url)) {//有缓存
SoftReference<Drawable> soft = imageCache.get(url);
if (null != imageView)
imageView.setImageDrawable(soft.get());
if (callback != null) {
callback.onImageLoaded(soft.get());
}
} else {
executorService.execute(new Runnable() {
@Override
public void run() {
final Drawable drawable = loadFromURl(url);
imageCache.put(url, new SoftReference<Drawable>(drawable));
handler.post(new Runnable() {
@Override
public void run() {
if (null != imageView)
imageView.setImageDrawable(drawable);
if (callback != null) {
callback.onImageLoaded(drawable);
}
}
});
}
});
}
代码执行效果如下图所示:
3.RunnableQueue
该类实现了Runnable在Queue中列队执行的功能,可以通过addTask方法向Queue中添加任务:
public void addTask(final T mr) {
if (mES == null) {
mES = Executors.newSingleThreadExecutor();
notifyWork();
}
if (taskQueue == null) {
taskQueue = new ConcurrentLinkedQueue<>();
}
if (taskMap == null) {
taskMap = new ConcurrentHashMap<>();
}
mES.execute(new Runnable() {
@Override
public void run() {
/**
* 插入一个Runnable到任务队列中
* */
taskQueue.offer(mr);
// taskQueue.add(mr);
notifyWork();
}
});
}
public void start() {
Log.v(TAG, "Queue Size --> " + taskQueue.size());
if (mES == null || taskQueue == null || taskMap == null) {
Log.i("KKK", "某资源是不是已经被释放了?");
return;
}
mES.execute(new Runnable() {
@Override
public void run() {
if (isRuning) {
T myRunnable = null;
synchronized (lock) {
// 从线程队列中取出一个Runnable对象来执行,如果此队列为空,则调用poll()方法会返回null
myRunnable = taskQueue.poll();
if (myRunnable == null) {
isNotify = true;
}
}
if (myRunnable != null) {
taskMap.put(mES.submit(myRunnable), myRunnable);
}
}
}
});
}