性能優(yōu)化最佳實(shí)踐之多線程操作
今天本來(lái)是想分析一下Handler源碼,在Android Developers看到了對(duì)多線程比較完整的介紹,覺(jué)得應(yīng)該從線程學(xué)起。這個(gè)文章是對(duì)它的整理、理解和發(fā)散,包括對(duì)線程的理解。其中一些簡(jiǎn)單的東西就省略了。
發(fā)送動(dòng)作給多個(gè)線程
指定部分代碼運(yùn)行在Thread里面
Thread和Runnable是基本的類,獨(dú)自運(yùn)作的話能力有限;但是他們是很多強(qiáng)大的類比如 HandlerThread, AsyncTask, and IntentService的基礎(chǔ)。同時(shí)Thread和Runnable還是ThreadPoolExecutor的基礎(chǔ),ThreadPoolExecutor自動(dòng)管理進(jìn)程和任務(wù)隊(duì)列,甚至能并行運(yùn)行多個(gè)線程。
Runnable接口只有一個(gè)run()方法。把想要運(yùn)行在新的線程里的內(nèi)容寫(xiě)在run()里面。注意Runnable不會(huì)運(yùn)行在UI Thread中。在run()方法的開(kāi)始,可以使用Process.setThreadPriority(),可以減少Runnable對(duì)象進(jìn)程和UI進(jìn)程之間的競(jìng)爭(zhēng)。
疑問(wèn),為什么實(shí)現(xiàn)Runnable接口就可以實(shí)現(xiàn)多線程?
學(xué)線程的時(shí)候,一般會(huì)有學(xué)到兩種方法:
- 繼承Thread類 :
MyThread().start(); - 實(shí)現(xiàn)Runnable接口 :
new Thread(myRunnable).start();
但其實(shí)Runnable只是一個(gè)interface,里面只有一個(gè)run方法;為什么它可以實(shí)現(xiàn)多線程呢?
從Thread源碼中看到,Thread也是實(shí)現(xiàn)了Runnable接口的,也覆寫(xiě)了run方法,方法說(shuō)明:
- 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.
也就是說(shuō),如果這個(gè)Thread是通過(guò)獨(dú)立的Runnable run對(duì)象構(gòu)建的,那么那個(gè)Runnable run方法會(huì)被調(diào)用,否則,這個(gè)方法什么都不做并且返回。
Thread的構(gòu)造方法傳入一個(gè)Runnable(它的構(gòu)造方法是重載的,這里取了其中一個(gè)):
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
init方法接收這個(gè)Runnable為target,然后如果target不為空,就執(zhí)行Runnable的run方法:
@Override
public void run() {
if (target != null) {
target.run();
}
}
真是接口的典型應(yīng)用啊。Runnable只是為了實(shí)現(xiàn)Thread不能實(shí)現(xiàn)的「多繼承」而出現(xiàn)的。如果不執(zhí)行start方法,是不會(huì)在新線程中執(zhí)行run里面的代碼的。start方法會(huì)讓JVM調(diào)用當(dāng)前Thread的run方法。
大部分資料都會(huì)推薦大家用Runnable多過(guò)繼承Thread,因?yàn)槿绻皇窍胗枚嗑€程中的run方法,沒(méi)必要繼承一個(gè)Thread,除非想要改變Thread中的某個(gè)行為。但是問(wèn)題是,這兩種方式難道不都是要new一個(gè)對(duì)象,占用同樣多的內(nèi)存空間么。。
-Jan 5
Reference:
[1]http://www.tuicool.com/articles/Z3aEbeF