實(shí)現(xiàn)方式和繼承方式有什么區(qū)別呢?
*區(qū)別:
*繼承Thread:線程代碼存放在Thread子類run方法中
*實(shí)現(xiàn)Runnable:線程代碼存放在接口的子類的run方法中
*實(shí)現(xiàn)方式的好處:避免了單繼承的局限性
*在定義線程時(shí),建議使用實(shí)現(xiàn)方式,當(dāng)然如果一個(gè)類沒有繼承父類,那么也可以通過繼承Thread類來實(shí)現(xiàn)多線程
*注意:Runnable接口沒有拋出異常,那么實(shí)現(xiàn)它的類只能是try-catch不能throws
*Java對(duì)多線程的安全問題提供了專業(yè)的解決方式就是同步代碼塊synchronized(對(duì)象){需要同步的代碼}
*同步的前提:
*1.有2個(gè)及以上的線程
*2.多個(gè)線程使用用一個(gè)鎖(對(duì)象)
*同步的好處:解決了多線程的安全問題
*同步的弊端:多個(gè)線程需要判斷鎖,較為消耗資源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
package 多線程; class Ticket implements Runnable { // private static int tick = 100; private int tick= 100 ; Object obj = new Object(); //創(chuàng)建一個(gè)對(duì)象或者自己重新寫一個(gè)類來創(chuàng)建一個(gè)對(duì)象下面同步關(guān)鍵字需要用到 @Override public void run() { while ( true ) { synchronized (obj) // synchronized(this) { if (tick> 0 ){ try {Thread.sleep( 10 );} catch (Exception e) { } System.out.println(Thread.currentThread().getName()+ "...銷售:" +(tick--)+ "號(hào)票" ); // tick--; } else { break ; } } } } } public class Test { public static void main(String[] args) { Ticket t = new Ticket(); //創(chuàng)建一個(gè)實(shí)現(xiàn)了Runnable接口的類 //創(chuàng)建4個(gè)多線程對(duì)象并傳遞上面接口對(duì)象給其構(gòu)造方法 Thread t1 = new Thread(t); //創(chuàng)建了一個(gè)線程 Thread t2 = new Thread(t); //創(chuàng)建了一個(gè)線程 Thread t3 = new Thread(t); //創(chuàng)建了一個(gè)線程 Thread t4 = new Thread(t); //創(chuàng)建了一個(gè)線程 //開啟線程 t1.start(); t2.start(); t3.start(); t4.start(); } } |
以上就是小編為大家?guī)淼膉ava實(shí)現(xiàn)多線程的兩種方式繼承Thread類和實(shí)現(xiàn)Runnable接口的方法的全部?jī)?nèi)容了,希望對(duì)大家有所幫助,多多支持服務(wù)器之家~