一、什麼是執行緒同步、非同步?
(更多面試題推薦:java面試題)
#同步(synchronous)就是協同步調,依照預定的先後序進行運作。
非同步就是和同步相對,不阻塞,同時運作。
二、什麼是執行緒不安全?如何解決? (重點)
什麼叫線程安全?
如果你的程式碼所在的進程中有多個執行緒在同時執行,而這些執行緒可能會同時運行這段程式碼。如果每次運行結果和單執行緒運行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的。
或說:一個類別或程式所提供的介面對於執行緒來說是原子運算或多個執行緒之間的切換不會導致該介面的執行結果存在二義性,也就是說我們不用考慮同步的問題。
線程安全性問題都是由全域變數及靜態變數所引起的。
若每個執行緒中對全域變數、靜態變數只有讀取操作,而無寫入操作,一般來說,這個全域變數是執行緒安全的;若有多個執行緒同時執行寫入操作,一般都需要考慮線程同步,否則就可能影響線程安全。
(相關教學推薦:java入門程式)
為什麼ArrayList執行緒不安全?不安全為什麼要使用?如何解決線程不安全?
一個ArrayList ,在新增一個元素的時候,它可能會有兩步驟來完成:
1、在Items[Size] 的位置存放此元素;
2、增大Size 的值。
在單執行緒運行的情況下,如果Size = 0,新增一個元素後,此元素在位置0,而且Size=1;而如果是在多執行緒情況下,例如有兩個執行緒,線程A 先將元素存放在位置0。
但此時 CPU 調度執行緒A暫停,執行緒 B 得到運行的機會。線程B也向此ArrayList 添加元素,因為此時Size 仍然等於0 (注意哦,我們假設的是添加一個元素是要兩個步驟哦,而線程A僅僅完成了步驟1),所以線程B也將元素存放在位置0。然後線程A和線程B都繼續運行,都增加 Size 的值。
那好,現在我們來看看 ArrayList 的情況,元素其實只有一個,存放在位置 0,而 Size 卻等於 2。這就是「線程不安全」了。
如何解決?
加鎖(物件鎖、鎖定程式碼區塊)、自旋CAS方式(樂觀鎖)、使用java提供的線程安全的資料類別
三、如何建立一個線程?有幾種方法?
1、繼承Thread類別
2、實作Runnable介面
3、實作Callable介面
四、是使用Runnalbe接口好?還是繼承Thread類別好?
實作Runnable介面比較好一些。
1、因為實作Runnable介面可以避免Java單繼承的限制。
當一個類別繼承了Thread,就不可以在繼承其他類別了。而當一個類別實作了Runnable,它一樣可以繼承其他類別。
2、更符合物件導向的設計
run()方法的作用是用來封裝執行緒要執行的程式碼。那麼run()方法所屬的對象,就是執行緒任務對象。 Thread類別的子類別物件即使執行緒對象,又是執行緒任務對象。耦合性很強。
有了Runnable接口,可以將執行緒任務和執行緒進行解耦,提高了程式的擴充性。
(相關影片教學推薦:java影片教學)
#五、sleep()和wait()有什麼區別?
sleep是線程類別(Thread)的方法,導致此線程暫停執行指定時間,把執行機會給其他線程,但是監控狀態仍然保持,到時後會自動恢復。呼叫sleep不會釋放物件鎖定。
wait是Object類別的方法,對此物件呼叫wait方法導致本執行緒放棄物件鎖,進入等待此物件的等待鎖定池,只有針對此物件發出notify方法(或notifyAll)後本執行緒才進入物件鎖定池準備取得物件鎖定進入運作狀態。
如果變數被宣告為volatile,在每次訪問時都會和主存一致;如果變數在同步方法或同步區塊中被訪問,當在方法或區塊的入口處獲得鎖以及方法或區塊退出時釋放鎖定時變數被同步。
以上是java經典面試題集錦(五)的詳細內容。更多資訊請關注PHP中文網其他相關文章!