繼承Thread類,須要覆蓋方法 run()方法,在建立Thread類的子類時須要重寫 run(),加入線程所要執行的代便可。java
下邊是一個賣票程序小例子:編程
1 package ThreadOne; 2 3 public class ThreadByExtends { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 new MyThread().start(); 8 new MyThread().start(); 9 new MyThread().start(); 10 } 11 12 } 13 14 class MyThread extends Thread { 15 private int ticket = 5; 16 17 public void run() { 18 19 for (int i = 0; i < 10; i++) { 20 if (ticket > 0) { 21 System.out.println("車票第" + ticket-- + "張"); 22 } 23 } 24 } 25 26 }
輸出結果爲:安全
這樣代碼的寫法簡單,符合你們的習慣,可是直接繼承Thread類有一個很大的缺點,由於「java類的繼承是單一的,extends後面只能指定一個父類」,全部若是當前類繼承Thread類以後就不能夠繼承其餘類。若是咱們的類已經從一個類繼承(如Swing繼承自 Panle 類、JFram類等),則沒法再繼承 Thread 類,這時若是咱們又不想創建一個新的類,應該怎麼辦呢?多線程
若是要實現多繼承就得要用implements,Java 提供了接口 java.lang.Runnable 來解決上邊的問題。異步
Runnable是能夠共享數據的,多個Thread能夠同時加載一個Runnable,當各自Thread得到CPU時間片的時候開始運行Runnable,Runnable裏面的資源是被共享的,因此使用Runnable更加的靈活。spa
下邊仍是賣票例子:.net
1 package ThreadOne; 2 3 public class ThreadRunnable { 4 5 public static void main(String[] args) { 6 MyThread1 myThread = new MyThread1(); 7 new Thread(myThread).start(); 8 new Thread(myThread).start(); 9 } 10 } 11 12 class MyThread1 implements Runnable { 13 14 private int ticket = 5; 15 16 public void run() { 17 for (int i = 0; i < 10; i++) { 18 if (ticket > 0) { 19 System.out.println("ticket = " + ticket--); 20 } 21 } 22 } 23 24 }
輸出結果:線程
Runnable是執行工做的獨立任務,可是它不返回任何值。若是你但願任務在完成的能返回一個值,那麼能夠實現Callable接口而不是Runnable接口。在Java SE5中引入的Callable是一種具備類型參數的泛型,它的參數類型表示的是從方法call()(不是run())中返回的值。code
例子以下:orm
1 package ThreadOne; 2 3 import java.awt.Panel; 4 import java.util.concurrent.Callable; 5 import java.util.concurrent.Future; 6 import java.util.concurrent.FutureTask; 7 8 public class ThreadCallable extends Panel { 9 10 public static void main(String[] args) { 11 12 MyThread2 myThread2 = new MyThread2(); 13 14 FutureTask<Integer> futureTask = new FutureTask<>(myThread2); 15 new Thread(futureTask, "線程名:有返回值的線程2").start(); 16 17 try { 18 System.out.println("子線程的返回值:" + futureTask.get()); 19 } catch (Exception e) { 20 e.printStackTrace(); 21 } 22 } 23 } 24 25 class MyThread2 implements Callable<Integer> { 26 27 public Integer call() throws Exception { 28 System.out.println("當前線程名——" + Thread.currentThread().getName()); 29 int i = 0; 30 for (; i < 5; i++) { 31 System.out.println("循環變量i的值:" + i); 32 } 33 34 return i; 35 } 36 37 }
運行結果以下:
實現Runnable接口相比繼承Thread類有以下優點:
實現Runnable接口和實現Callable接口的區別: