本文为楼主原创,转载请表明出处:http://blog.csdn.net/Suma_sun/article/details/51584026
在程序开发中,为了让程序表现的更快更流畅,我们会使用多线程来提升应用的并发性能。但多线程并发代码是一个棘手的问题,线程的生命周期处理不好就会造成内存泄漏。
new Thread(){
@Override
public void run() {
doSomeThing();
}
}.start();
上面给出了一个最简单的新建线程并执行任务,也是最不好管理的。为什么?run里面的方法很可能很耗时,直接new出来的线程没有一个对象去接收其句柄,连打断都做不到,只能等待内部错误停止或者任务执行完毕。就算不使用匿名类的方式操作,停止线程光用interrupt()是不够的,该方法只有在线程调用sleep()、join()、wait()交出时间片(阻塞)的时候,它将接收到一个中断异常(InterruptedException),从而提早结束该线程。所以一般都是在run方法里各种操作之前先判断下标志位,是否需要继续执行任务,向外暴露这个标志位的接口,让其变成可控线程。当然普通的thread是满足不了你的,你需要继承thread自行处理标志位的操作,当然如果写成内部类的话最好写成静态内部类,这样避免持有外部类的引用造成泄漏。
经常new Thread().start()的话会加大性能的开销,虽然并发量上去了(不要无止尽的新建线程,处理线程跟cpu核数有关,线程数超出CPU核数过多反而会降低效率,并发得不偿失,因为切换线程是要切换上下文环境的,此操作开销十分大),但是开销变大了。所以管理好线程的个数、复用成为重中之重。
你以为这样就结束了?
打出上面那段话我突然想起小时候看的《西游记后传》里的一句经典台词——我还没出力呢,你就趴下了。
Android多线程性能优化前篇-UI线程源码剖析
ps:其实真正的标题在这(>_<:.),其实原本没打算写ui线程的,在整合资料的时候看到了,就顺便写写吧,没想到一写就写那么多…标题都对不上号了,只好修改了
上面说了Thread不足的地方,各位可以思考下有什么解决方案,下篇我再给大家介绍几个方案。
操作UI线程
- Activity.runOnUiThread(Runnable)
- View.post(Runnable) 、 View.postDelay(Runnable , long)
- Handler
- AsyncTask
- IntentService
首先是Handker这个大家天天用应该不用我说了吧,不清楚的可以看我另一篇面试经典题Handler机制回答
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
上面给出了runOnUiThread的源码,看到关键对象mHandler就知道了,当前线程如果不在主线程(UI线程)就调用activity内的全局handler进行UI操作。PS:在我打开源码之前就想到里里面估计也是有一个Handler来执行UI操作,没想到打开居然中标了,感觉最近还是有些许提升的。哈哈,装完逼,我继续讲~
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
return true;
}
public boolean postDelayed(Runnable action, long delayMillis) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.postDelayed(action, delayMillis);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
return true;
}
从源码可以看出当attachInfo不为空的时候会调用其内部持有的handler进行UI操作。那AttachInfo是什么鬼呢?
/**
* A set of information given to a view when it is attached to its parent
* window.
*/
final static class