參考文章
如何創(chuàng)建并運行java線程 | 并發(fā)編程網(wǎng) – ifeve.com
(此文摘取了其中一些知識點航揉,具體知識點及源碼請于鏈接處觀看)
創(chuàng)建并運行java線程
1.創(chuàng)建Thread的子類
注意:
一旦線程啟動后start方法就會立即返回驶乾,而不會等待到run方法執(zhí)行完畢才返回邑飒。就好像run方法是在另外一個cpu上執(zhí)行一樣。
2.實現(xiàn)Runnable接口
為了使線程能夠執(zhí)行run()方法级乐,需要在Thread類的構(gòu)造函數(shù)中傳入?MyRunnable的實例對象疙咸。示例如下:
Thread thread = new Thread(new MyRunnable());
thread.start();
3.創(chuàng)建子類還是實現(xiàn)Runnable接口?
線程池可以有效的管理實現(xiàn)了Runnable接口的線程风科,如果線程池滿了撒轮,新的線程就會排隊等候執(zhí)行乞旦,直到線程池空閑出來為止。而如果線程是通過實現(xiàn)Thread子類實現(xiàn)的题山,這將會復(fù)雜一些
4.常見錯誤:調(diào)用run()方法而非start()方法
事實上,run()方法并非是由剛創(chuàng)建的新線程所執(zhí)行的兰粉,而是被創(chuàng)建新線程的當(dāng)前線程所執(zhí)行了。也就是被執(zhí)行上面兩行代碼的線程所執(zhí)行的顶瞳。想要讓創(chuàng)建的新線程執(zhí)行run()方法玖姑,必須調(diào)用新線程的start方法。
5.獲取線程名
Thread子類:調(diào)用getName()
Runnable的實現(xiàn)類
線程安全與共享資源
允許被多個線程同時執(zhí)行的代碼稱作線程安全的代碼慨菱。線程安全的代碼不包含競態(tài)條件焰络。當(dāng)多個線程同時更新共享資源時會引發(fā)競態(tài)條件。
1.局部變量和對象
局部變量存儲在線程自己的棧中符喝。也就是說闪彼,局部變量永遠(yuǎn)也不會被多個線程共享
2.局部對象的引用
所有的對象都存在共享堆中。如果在某個方法中創(chuàng)建的對象不會逃逸出(譯者注:即該對象不會被其它方法獲得协饲,也不會被非局部變量引用到)該方法畏腕,那么它就是線程安全的。實際上囱稽,哪怕將這個對象作為參數(shù)傳給其它方法郊尝,只要別的線程獲取不到這個對象,那它仍是線程安全的战惊。
public void someMethod(){
? LocalObject localObject = new LocalObject();
? localObject.callMethod();
? method2(localObject);
}
public void method2(LocalObject localObject){
? localObject.setValue("value");
}
樣例中LocalObject對象沒有被方法返回流昏,也沒有被傳遞給someMethod()方法外的對象。每個執(zhí)行someMethod()的線程都會創(chuàng)建自己的LocalObject對象吞获,并賦值給localObject引用况凉。因此,這里的LocalObject是線程安全的各拷。事實上刁绒,整個someMethod()都是線程安全的。即使將LocalObject作為參數(shù)傳給同一個類的其它方法或其它類的方法時烤黍,它仍然是線程安全的知市。當(dāng)然,如果LocalObject通過某些方法被傳給了別的線程速蕊,那它就不再是線程安全的了嫂丙。
線程控制逃逸規(guī)則
如果一個資源的創(chuàng)建,使用规哲,銷毀都在同一個線程內(nèi)完成跟啤,
且永遠(yuǎn)不會脫離該線程的控制,則該資源的使用就是線程安全的。
資源可以是對象隅肥,數(shù)組竿奏,文件,數(shù)據(jù)庫連接腥放,套接字等等泛啸。Java中你無需主動銷毀對象,所以“銷毀”指不再有引用指向?qū)ο蟆?/p>
即使對象本身線程安全捉片,但如果該對象中包含其他資源(文件平痰,數(shù)據(jù)庫連接),整個應(yīng)用也許就不再是線程安全的了伍纫。比如2個線程都創(chuàng)建了各自的數(shù)據(jù)庫連接宗雇,每個連接自身是線程安全的,但它們所連接到的同一個數(shù)據(jù)庫也許不是線程安全的莹规。比如赔蒲,2個線程執(zhí)行如下代碼:
????檢查記錄X是否存在,如果不存在良漱,插入X
如果兩個線程同時執(zhí)行舞虱,而且碰巧檢查的是同一個記錄,那么兩個線程最終可能都插入了記錄:
線程1檢查記錄X是否存在母市。檢查結(jié)果:不存在
線程2檢查記錄X是否存在矾兜。檢查結(jié)果:不存在
線程1插入記錄X
線程2插入記錄X