面試題-實現多線程的方式

面試題-實現多線程的方式

Java中實現多線程的方式有下面三種:java

  • 繼承Thread類,重寫run方法
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());
    }
}
  • 實現Runnable接口,重寫run方法
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());
    }
}
  • 經過Callable和FutureTask建立線程(最終仍是Thread啓動)
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買票就是這個邏輯,固然這邊沒有考慮到併發下票數超賣的狀況。接口實現的方式可讓多個線程作同一件事情。

推薦相關閱讀:

  • 《註解面試題-請了解下》

  • 《反射面試題-請了解下》
    更多技術分享請加我微信,我拉你進羣進行交流:
    面試題-實現多線程的方式
相關文章
相關標籤/搜索