標籤:方法 cpu 成員 結束 time 對象建立 調用 一個 sel
使用Runnable介面建立線程Runnable介面
兩種線程構造方式的比較
- 使用Runnable介面
可以將cpu、代碼和資料分開,形成清晰的模型,還可以從其他類繼承
- 直接繼承Thread類
編寫簡單,直接繼承,重寫run方法,不能再從其他類繼承
執行個體
運行結果:
開啟線程
主線程結束
thread3準備休眠:1750
thread1準備休眠:1889
thread2準備休眠:186
thread2休眠結束
thread3休眠結束
thread1休眠結束
線程內部資料共用
用同一個實現了Runnable介面的對象作為參數建立多個線程,多個線程共用同一個對象中的相同的資料
運行結果:
開啟線程
結束線程
thread1準備休眠:2224
thread3準備休眠:2224
thread2準備休眠:2224
thread1休眠結束
thread2休眠結束
thread3休眠結束
說明:
因為是用同一個Runnable類型對象建立的3個新線程,這三個線程就共用了這個對象的私人成員sleepTime,在本次運行中,三個線程都休眠了2224毫秒
安全執行緒問題:
對於有一些應用,資料共用是不安全的 ,而且恰好應用中的某個類是單例的,那麼就不要把資料寫為成員變數,比如HttpServlet。
案例2:獨立且同時啟動並執行線程有時需要共用一些資料並且考慮到彼此的狀態和動作.
用三個線程類比三個售票口,總共出售20張票
用3個線程模仿3個售票口的售票行為
這3個線程應該共用20張票的資料
運行結果:
開始售票
售票口1號出售票號:20
.....
售票口3號出售票號:3
售票口3號出售票號:1
售票口1號出售票號:4
售票口1號結束
售票口3號結束
售票口2號出售票號:2
售票口2號結束
說明:
在這個例子中,建立了3個線程,每個線程調用的是同一個SellTickets對象中的run()方法,訪問的是同一個對象中的變數(tickets)
如果是通過建立Thread的子類來類比售票過程,再建立3個線程,則每個線程都會有各自的方法和變數,雖然方法是相同的,但變數卻是各自有20張票,因而結果將會是各賣出20張票,和業務需求不符合了。
java多線程(六)