1.首先來說說創建線程的兩種方式
一種方式是繼承Thread類,並重寫run()方法
1 public class MyThread extends Thread{ 2 @Override 3 public void run() { 4 // TODO Auto-generated method stub 5 6 } 7 } 8 //線程使用 9 MyThread mt = new MyThread(); //創建線程 10 mt.start(); //啟動線程
另外一種方式是實現Runnable接口
1 public class MyThread implements Runnable{ 2 @Override 3 public void run() { 4 // TODO Auto-generated method stub 5 6 } 7 } 8 //線程使用 9 MyThread mt = new MyThread(); 10 Thread thread = new Thread(mt);//創建線程 11 thread.start(); //啟動線程
2.兩種方式創建線程比較
第一點:通過創建線程方式可以看出,一個是繼承一個是實現接口,但是Java是只能繼承一個父類,可以實現多個接口的一個特性,所以說采用Runnable方式可以避免Thread方式由於Java單繼承帶來的缺陷。
第二點:Runnable的代碼可以被多個線程共享(Thread實例),適合於多個多個線程處理統一資源的情況。
舉例說明:模擬賣票,假設還剩5張票,分別采用兩種方式來創建線程模擬
TicketThread.java //采用繼承方式模擬3個窗口賣5張票的情況
1 public class TicketThread { 2 public static void main(String[] args) { 3 //創建了3個線程,模擬三個窗口賣票 4 MyThread mt1 = new MyThread("線程一"); 5 MyThread mt2 = new MyThread("線程二"); 6 MyThread mt3 = new MyThread("線程三"); 7 8 //啟動線程 9 mt1.start(); 10 mt2.start(); 11 mt3.start(); 12 } 13 14 } 15 16 class MyThread extends Thread{ 17 private int num = 5;//模擬還剩余5張票 18 private String name;//用來表示線程名稱 19 20 public MyThread(String name){ 21 this.name = name; 22 } 23 24 @Override 25 public void run() { 26 while(num > 0){ 27 num--; 28 System.out.println(name+"賣出了一張票,剩余票數為"+num); 29 } 30 } 31 }
運行結果為:
1 線程一賣出了一張票,剩余票數為4 2 線程一賣出了一張票,剩余票數為3 3 線程一賣出了一張票,剩余票數為2 4 線程一賣出了一張票,剩余票數為1 5 線程一賣出了一張票,剩余票數為0 6 線程二賣出了一張票,剩余票數為4 7 線程二賣出了一張票,剩余票數為3 8 線程二賣出了一張票,剩余票數為2 9 線程二賣出了一張票,剩余票數為1 10 線程二賣出了一張票,剩余票數為0 11 線程三賣出了一張票,剩余票數為4 12 線程三賣出了一張票,剩余票數為3 13 線程三賣出了一張票,剩余票數為2 14 線程三賣出了一張票,剩余票數為1 15 線程三賣出了一張票,剩余票數為0
可以看出共賣出了15張票,變成了每個線程都有5張票了
TicketRunnable.java //采用Runnable實現
1 public class TickerRunnable{ 2 public static void main(String[] args) { 3 MyThread mt = new MyThread(); 4 //同樣創建3個線程 5 Thread t1 = new Thread(mt, "線程一"); 6 Thread t2 = new Thread(mt, "線程二"); 7 Thread t3 = new Thread(mt, "線程三"); 8 //啟動線程 9 t1.start(); 10 t2.start(); 11 t3.start(); 12 } 13 14 } 15 16 class MyThread implements Runnable{ 17 private int num = 5;//模擬還剩余5張票 18 19 @Override 20 public void run() { 21 while(num > 0){ 22 num--; 23 System.out.println(Thread.currentThread().getName()+"賣出了一張票,剩余票數為"+num); 24 } 25 } 26 }
運行結果為:
1 線程一賣出了一張票,剩余票數為4 2 線程三賣出了一張票,剩余票數為3 3 線程三賣出了一張票,剩余票數為1 4 線程二賣出了一張票,剩余票數為0 5 線程一賣出了一張票,剩余票數為2
這樣可以看出多個線程共享了Runnbale里面的5這個變量,至於結果為什么不是輸出剩余票數4 3 2 1 0,這個是由於線程的調度問題造成的,每次運行都會看到不一樣的結果。