多執行緒優勢:
程序之間不能共享記憶體,但執行緒之間共享記憶體非常容易;
系統建立執行緒所分配的資源相對建立程序而言,代價非常小。

第一種實現方法—繼承Thread類

繼承Thread類,重寫run()方法,加入執行緒所要執行的代即可。
例項:

public class ThreadTest {
      public static void main(String[] args) {
          new MyThread().start();
          new MyThread().start();
          new MyThread().start();
     }

}

class MyThread extends Thread {
     private int ticket = 5; 
     public void run() {

         for (int i = 0; i < 10; i++) {
             if (ticket > 0) {
                 System.out.println("車票第" + ticket-- + "張");
             }
         }
     }

}

這樣程式碼的寫法簡單,符合大家的習慣,但是直接繼承Thread類有一個很大的缺點,因為“java類的繼承是單一的,extends後面只能指定一個父類”,所有如果當前類繼承Thread類之後就不可以繼承其他類。如果我們的類已經從一個類繼承(如Swing繼承自 Panle 類、JFram類等),則無法再繼承 Thread 類,這時如果我們又不想建立一個新的類,應該怎麼辦呢?

第二種實現方法—實現Runnable介面

如果要實現多繼承就得要用implements,Java 提供了介面 java.lang.Runnable 來解決上邊的問題。

Runnable是可以共享資料的,多個Thread可以同時載入一個Runnable,當各自Thread獲得CPU時間片的時候開始執行Runnable,Runnable裡面的資源是被共享的,所以使用Runnable更加的靈活。

例項:

 public class ThreadRunnable {

     public static void main(String[] args) {
         MyThread1 myThread = new MyThread1();
         new Thread(myThread).start();
         new Thread(myThread).start();
     }
 }

 class MyThread1 implements Runnable {

     private int ticket = 5;

     public void run() {
         for (int i = 0; i < 10; i++) {
             if (ticket > 0) {
                 System.out.println("ticket = " + ticket--);
             }
         }
     }

}

第三種實現方法—實現Callable介面

Runnable是執行工作的獨立任務,但是它不返回任何值。如果你希望任務在完成後能返回一個值,那麼可以實現Callable介面而不是Runnable介面。在Java SE5中引入的Callable是一種具有型別引數的泛型,它的引數型別表示的是從方法call()(不是run())中返回的值。

例項:

  import java.awt.Panel;
  import java.util.concurrent.Callable;
  import java.util.concurrent.Future;
  import java.util.concurrent.FutureTask;

  public class ThreadCallable extends Panel {

     public static void main(String[] args) {

         MyThread2 myThread2 = new MyThread2();

         FutureTask<Integer> futureTask = new FutureTask<>(myThread2);
         new Thread(futureTask, "執行緒名:有返回值的執行緒2").start();

         try {
             System.out.println("子執行緒的返回值:" + futureTask.get());
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 }

 class MyThread2 implements Callable<Integer> {

     public Integer call() throws Exception {
         System.out.println("當前執行緒名——" + Thread.currentThread().getName());
         int i = 0;
         for (; i < 5; i++) {
             System.out.println("迴圈變數i的值:" + i);
        } 
         return i;
     } 
}