1.首先來說說創(chuàng)建線程的兩種方式
一種方式是繼承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(); //創(chuàng)建線程10 mt.start(); //啟動線程
另外一種方式是實(shí)現(xiàn)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);//創(chuàng)建線程11 thread.start(); //啟動線程
2.兩種方式創(chuàng)建線程比較
第一點(diǎn):通過創(chuàng)建線程方式可以看出,一個是繼承一個是實(shí)現(xiàn)接口,但是java是只能繼承一個父類,可以實(shí)現(xiàn)多個接口的一個特性,所以說采用Runnable方式可以避免Thread方式由于Java單繼承帶來的缺陷。
第二點(diǎn):Runnable的代碼可以被多個線程共享(Thread實(shí)例),適合于多個多個線程處理統(tǒng)一資源的情況。
舉例說明:模擬賣票,假設(shè)還剩5張票,分別采用兩種方式來創(chuàng)建線程模擬
TicketThread.java //采用繼承方式模擬3個窗口賣5張票的情況
1 public class TicketThread { 2 public static void main(String[] args) { 3 //創(chuàng)建了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 @Override25 public void run() {26 while(num > 0){27 num--;28 System.out.println(name+"賣出了一張票,剩余票數(shù)為"+num);29 }30 }31 }
運(yùn)行結(jié)果為:
1 線程一賣出了一張票,剩余票數(shù)為4 2 線程一賣出了一張票,剩余票數(shù)為3 3 線程一賣出了一張票,剩余票數(shù)為2 4 線程一賣出了一張票,剩余票數(shù)為1 5 線程一賣出了一張票,剩余票數(shù)為0 6 線程二賣出了一張票,剩余票數(shù)為4 7 線程二賣出了一張票,剩余票數(shù)為3 8 線程二賣出了一張票,剩余票數(shù)為2 9 線程二賣出了一張票,剩余票數(shù)為110 線程二賣出了一張票,剩余票數(shù)為011 線程三賣出了一張票,剩余票數(shù)為412 線程三賣出了一張票,剩余票數(shù)為313 線程三賣出了一張票,剩余票數(shù)為214 線程三賣出了一張票,剩余票數(shù)為115 線程三賣出了一張票,剩余票數(shù)為0
可以看出共賣出了15張票,變成了每個線程都有5張票了
TicketRunnable.java //采用Runnable實(shí)現(xiàn)
1 public class TickerRunnable{ 2 public static void main(String[] args) { 3 MyThread mt = new MyThread(); 4 //同樣創(chuàng)建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 @Override20 public void run() {21 while(num > 0){22 num--;23 System.out.println(Thread.currentThread().getName()+"賣出了一張票,剩余票數(shù)為"+num);24 }25 }26 }
運(yùn)行結(jié)果為:
1 線程一賣出了一張票,剩余票數(shù)為42 線程三賣出了一張票,剩余票數(shù)為33 線程三賣出了一張票,剩余票數(shù)為14 線程二賣出了一張票,剩余票數(shù)為05 線程一賣出了一張票,剩余票數(shù)為2
這樣可以看出多個線程共享了Runnbale里面的5這個變量,至于結(jié)果為什么不是輸出剩余票數(shù)4 3 2 1 0,這個是由于線程的調(diào)度問題造成的,每次運(yùn)行都會看到不一樣的結(jié)果。
新聞熱點(diǎn)
疑難解答
圖片精選