性能优化最佳实践之多线程操作
今天本来是想分析一下Handler
源码,在Android Developers看到了对多线程比较完整的介绍,觉得应该从线程学起。这个文章是对它的整理、理解和发散,包括对线程的理解。其中一些简单的东西就省略了。
发送动作给多个线程
指定部分代码运行在Thread里面
Thread和Runnable是基本的类,独自运作的话能力有限;但是他们是很多强大的类比如 HandlerThread, AsyncTask, and IntentService的基础。同时Thread和Runnable还是ThreadPoolExecutor
的基础,ThreadPoolExecutor
自动管理进程和任务队列,甚至能并行运行多个线程。
Runnable接口只有一个run()
方法。把想要运行在新的线程里的内容写在run()
里面。注意Runnable不会运行在UI Thread中。在run()方法的开始,可以使用Process.setThreadPriority()
,可以减少Runnable对象进程和UI进程之间的竞争。
疑问,为什么实现Runnable接口就可以实现多线程?
学线程的时候,一般会有学到两种方法:
- 继承Thread类 :
MyThread().start();
- 实现Runnable接口 :
new Thread(myRunnable).start();
但其实Runnable
只是一个interface
,里面只有一个run方法;为什么它可以实现多线程呢?
从Thread源码中看到,Thread也是实现了Runnable接口的,也覆写了run方法,方法说明:
- If this thread was constructed using a separate
- <code>Runnable</code> run object, then that
- <code>Runnable</code> object's <code>run</code> method is called;
- otherwise, this method does nothing and returns.
也就是说,如果这个Thread是通过独立的Runnable run对象构建的,那么那个Runnable run方法会被调用,否则,这个方法什么都不做并且返回。
Thread的构造方法传入一个Runnable(它的构造方法是重载的,这里取了其中一个):
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
init方法接收这个Runnable为target,然后如果target不为空,就执行Runnable的run方法:
@Override
public void run() {
if (target != null) {
target.run();
}
}
真是接口的典型应用啊。Runnable只是为了实现Thread不能实现的「多继承」而出现的。如果不执行start方法,是不会在新线程中执行run里面的代码的。start方法会让JVM调用当前Thread的run方法。
大部分资料都会推荐大家用Runnable多过继承Thread,因为如果只是想用多线程中的run方法,没必要继承一个Thread,除非想要改变Thread中的某个行为。但是问题是,这两种方式难道不都是要new一个对象,占用同样多的内存空间么。。
-Jan 5
Reference:
[1]http://www.tuicool.com/articles/Z3aEbeF