Android中多線程的實(shí)現(xiàn)

一、android線程間通信的幾種實(shí)現(xiàn)方式

1、Activity.runOnUiThread(Runnable)

2、View.post(Runnable); View.postDelay(Runnable,long)

3、Handler

4、AsyncTask

new MyAsyncTask().execute("test");

private class MyAsyncTask extends AsyncTask{

doInBackground(Object[] object){}

onPostExecute(Object o){

tv.setText(0.toString());

}

}

二、線程和進(jìn)程有什么區(qū)別?

一個(gè)進(jìn)程是一個(gè)獨(dú)立的運(yùn)行環(huán)境,它可以被看作一個(gè)程序或者一個(gè)應(yīng)用。而線程是在進(jìn)程中執(zhí)行的一個(gè)任務(wù)。線程是進(jìn)程的子集,一個(gè)進(jìn)程可以有很多線程,每條線程并行執(zhí)行不同的任務(wù)。不同的進(jìn)程使用不同的內(nèi)存空間,而所有的線程共享一片相同的內(nèi)存空間。但每個(gè)線程都擁有單獨(dú)的棧內(nèi)存用來存儲(chǔ)本地?cái)?shù)據(jù)。

三、多線程編程的好處

在多線程程序中,多個(gè)線程被并發(fā)的執(zhí)行以提高程序的效率,CPU不會(huì)因?yàn)槟硞€(gè)線程需要等待資源而進(jìn)入空閑狀態(tài)。多個(gè)線程共享堆內(nèi)存,因此創(chuàng)建多個(gè)線程去執(zhí)行一些任務(wù)會(huì)比創(chuàng)建多個(gè)進(jìn)程更好。

四、在java中實(shí)現(xiàn)線程

繼承Thread類;實(shí)現(xiàn)Runnable接口

五、啟動(dòng)一個(gè)線程是調(diào)run()還是start()方法

啟動(dòng)一個(gè)線程是調(diào)用start()方法,使線程所代表的虛擬處理機(jī)處于可運(yùn)行狀態(tài),這意味著它可以被JVM調(diào)度并執(zhí)行,這并不意味著線程就會(huì)立即運(yùn)行。run()方法是線程啟動(dòng)后要進(jìn)行回調(diào)(callback)的方法。

六、Thread類的sleep()方法和對(duì)象的wait()方法都可以讓線程暫停執(zhí)行,有什么區(qū)別。

sleep()方法是線程類(Thread)的靜態(tài)方法,調(diào)用這個(gè)方法會(huì)讓當(dāng)前線程暫停執(zhí)行指定的時(shí)間,將執(zhí)行機(jī)會(huì)讓給其他線程。但是對(duì)象的鎖依然保持,休眠時(shí)間結(jié)束會(huì)自動(dòng)恢復(fù)。wait()是Object類的方法,調(diào)用對(duì)象的wait方法導(dǎo)致當(dāng)前線程放棄對(duì)象的鎖,線程暫停執(zhí)行,進(jìn)入對(duì)象的等待池,只有調(diào)用對(duì)象的notify()方法或者notifyAll()方法,才能喚醒等待池中的線程進(jìn)入等鎖池,如果線程重新獲取到對(duì)象的鎖就可以進(jìn)入就緒狀態(tài)。

七、Android子線程真的不可以更新UI嗎?

在onCreate方法中創(chuàng)建的子線程訪問UI是一種極端的情況。

原因是:

ViewRootImpl會(huì)調(diào)用checkThread方法去檢查當(dāng)前訪問UI的線程是哪個(gè),如果不是UI線程則拋出異常。在執(zhí)行onCreate方法時(shí)ViewRootImpl還沒創(chuàng)建,無法去檢查當(dāng)前線程。ViewRootImpl的創(chuàng)建在onResume方法回調(diào)之后,如果在子線程中休眠一段時(shí)間去更新,很明顯這段時(shí)間ViewRootImpl已經(jīng)創(chuàng)建了,可以執(zhí)行checkThread方法檢查當(dāng)前線程,導(dǎo)致程序崩潰。

八、線程安全

當(dāng)多個(gè)線程訪問某個(gè)方法時(shí),不管通過怎樣的調(diào)用方式或者這些線程如何交替的執(zhí)行,我們主程序中不需要去做任何的同步,這個(gè)類的結(jié)果行為都是我們?cè)O(shè)想的正確行為,那么我們就可以說這個(gè)類是線程安全的。

1、synchronized。

public synchronized void threadMethod(){}

對(duì)于非靜態(tài)的synchronized方法,鎖的是對(duì)象本身也就是this,當(dāng)鎖住一個(gè)對(duì)象后,別的線程如果想要獲取鎖對(duì)象,那么必須等這個(gè)線程執(zhí)行完釋放鎖對(duì)象才可以,否則一直處于等待狀態(tài)。雖然加了這個(gè)關(guān)鍵字可以讓我們的線程變得安全,但是在使用的時(shí)候,也要注意縮小使用范圍,如果隨意使用很影響程序的性能,別的對(duì)象想拿到鎖,但是沒用還一直把鎖占用,浪費(fèi)了資源。

2、Lock

在需要的時(shí)候可以手動(dòng)獲取鎖和釋放鎖。

private Lock lock = new ReentrantLock();

private void nethod(Thread thread){

try{

lock.lock();//獲取鎖對(duì)象

System.out.printIn(thread.getName()+"獲得了鎖");

}catch(Exception e){

e.printStackTrace();

}finally{

lock.unlock();//釋放鎖對(duì)象

System.out.printIn(thread.getName()+"釋放了鎖");

}

}


Lock還有另一個(gè)方法tryLock(),Lock()方法是獲取鎖的時(shí)候,如果拿不到鎖就一直處于等待狀態(tài),直到拿到鎖,tryLock()有一個(gè)boolean返回值,如果沒有拿到鎖,返回false停止等待。

如果使用兩個(gè)線程測(cè)試,在線程1獲取到鎖后,線程2立馬進(jìn)來,發(fā)現(xiàn)鎖已經(jīng)被占用了,這個(gè)時(shí)候不會(huì)繼續(xù)等待,打印的日志也就只有線程1的日志了。

tryLock(2,TimeUnit.SECONDS);表示等待2秒,如果還獲取不到鎖對(duì)象,就不再等待。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容