Java中實現多線程的方式有下面三種:java
package fs; public class ThreadTest { public static void main(String[] args) { new MyThread().start(); } } class MyThread extends Thread { @Override public void run() { System.out.println("我是一個線程,我叫:"+Thread.currentThread().getName()); } }
package fs; public class ThreadTest { public static void main(String[] args) { new Thread(new MyRunnable()).start(); } } class MyRunnable implements Runnable { @Override public void run() { System.out.println("我是一個線程,我叫:"+Thread.currentThread().getName()); } }
package fs; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class ThreadTest { public static void main(String[] args) throws InterruptedException, ExecutionException { MyCallable call = new MyCallable(); FutureTask<String> task = new FutureTask<String>(call); new Thread(task).start(); String result = task.get(); System.out.println(result); } } class MyCallable implements Callable<String> { @Override public String call() throws Exception { return "Hello"; } }
上面的三種方式的區別在哪呢?面試
實現方式不一樣
第一種是繼承的方式,第二種和第三種都是實現接口的方式微信
返回值
第一種和第二種有一個共同的特色就是沒有返回值,而第三種是有返回值的多線程
擴展性
在Java中咱們都知道類只能單繼承,若是咱們本身建立的線程類是經過繼承Thread類的方法來實現的,那麼這個自定義類就不能再去擴展其餘的類,也就是說不能再去實現更加複雜的功能。
若是咱們用實現Runnable接口的方式來建立線程類,這樣就能夠避免Java單繼承所帶來的侷限性,經過接口多實現的特性進行擴展。併發
下面經過一段簡單的代碼來進行講解ide
定義一個售票窗口類線程
class TicketWindow extends Thread { int count = 100; @Override public void run() { System.out.println("窗口:"+Thread.currentThread().getName() + ":賣票啦" + count--); } } public class ThreadTest { public static void main(String[] args) throws InterruptedException, ExecutionException { for (int i = 0; i < 5; i++) { TicketWindow t = new TicketWindow(); t.start(); } } }
執行結果以下:code
窗口:Thread-1:賣票啦100 窗口:Thread-0:賣票啦100 窗口:Thread-2:賣票啦100 窗口:Thread-3:賣票啦100 窗口:Thread-4:賣票啦100
每一個線程都有本身的票總量,處理的都是本身的票,就是說每一個窗口各自賣各自的票,這就是繼承實現線程的特色,一個線程處理一件事情blog
下面來看接口實現方式的代碼繼承
class TicketWindow2 implements Runnable { int count = 100; @Override public void run() { System.out.println("窗口2:"+Thread.currentThread().getName() + ":賣票啦" + count--); } } public class ThreadTest { public static void main(String[] args) throws InterruptedException, ExecutionException { TicketWindow2 t2 = new TicketWindow2(); for (int i = 0; i < 5; i++) { new Thread(t2).start(); } } }
執行結果以下:
窗口2:Thread-0:賣票啦100 窗口2:Thread-3:賣票啦97 窗口2:Thread-1:賣票啦99 窗口2:Thread-2:賣票啦98 窗口2:Thread-4:賣票啦96
總共5個窗口也就是5個線程,執行的業務邏輯是相同的,至關於賣的是共享的票,我賣完了,你那邊就不能賣了,實際上也是這樣的,咱們在12306買票就是這個邏輯,固然這邊沒有考慮到併發下票數超賣的狀況。接口實現的方式可讓多個線程作同一件事情。
推薦相關閱讀:
《註解面試題-請了解下》