問題描述
在寫一個(gè)demo時(shí)需要使用線程來模擬網(wǎng)絡(luò)請(qǐng)求的方式表伦,結(jié)果在下拉刷新的時(shí)候進(jìn)度條顯示但是不旋轉(zhuǎn)。
使用線程的方式是:
//導(dǎo)致進(jìn)度條顯示但是不旋轉(zhuǎn)
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).run();
修改后為:
//正常
new Thread() {
@Override
public void run() {
super.run();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
于是產(chǎn)生疑問,兩者之間的區(qū)別是什么呢燥?
解答
首先線程有兩種方式實(shí)現(xiàn),一種通過Thread,另一種是通過實(shí)現(xiàn)Runnable接口,兩者在實(shí)現(xiàn)上和作用上均有區(qū)別禁筏。
Thread
實(shí)現(xiàn)方式:
//通過繼承方式
public class MyThread extends Thread {
@Override
public void run() {
super.run();
}
}
//調(diào)用
MyThread thread = new MyThread();
thread.start();
可以看出這種方式,只能單繼承衡招,因此有一定的局限性篱昔。
Runnable
//通過實(shí)現(xiàn)的方式
public class MyRunnable implements Runnable {
@Override
public void run() {
}
}
//調(diào)用
Thread thread1 = new Thread(new MyRunnable());
thread1.start();
可以看到實(shí)現(xiàn)Runnable也是通過Thread來調(diào)用的。
如果多個(gè)Thread也是同時(shí)調(diào)用的同一個(gè)Runnable對(duì)象始腾,因此在Runnable里面實(shí)現(xiàn)的run方法中處理的數(shù)據(jù)可以共享到每個(gè)Thread中州刽。因?yàn)槭褂玫氖菍?shí)現(xiàn)的方式,因此避免了單繼承的局限性浪箭。
問題分析
結(jié)果發(fā)現(xiàn)上面一個(gè)Thread調(diào)用的是run方法穗椅,進(jìn)行執(zhí)行,這是問題的關(guān)鍵奶栖。(開始看錯(cuò)匹表,以為是Thread()和Thread(Runnable)的區(qū)別導(dǎo)致的)
run()和start()運(yùn)行的區(qū)別
調(diào)用run方法,相當(dāng)于直接運(yùn)行run方法內(nèi)的代碼在同一個(gè)線程中運(yùn)行宣鄙,并不會(huì)開啟新的線程運(yùn)行袍镀。
因?yàn)槲沂窃贛ain線程中調(diào)用的run方法,因此相當(dāng)于讓Main線程sleep一秒后運(yùn)行框冀,導(dǎo)致進(jìn)度條沒有旋轉(zhuǎn)。
調(diào)用start方法敏簿,系統(tǒng)會(huì)開啟一個(gè)新線程執(zhí)行run方法里面的代碼明也。因此不會(huì)阻塞Main線程。