Java多線程系列--多線程的實現方式

前言

  Java多線程實現方式主要有如下四種:繼承Thread類;實現Runnable接口;實現Callable接口通過FutureTask包裝器來創建Thread線程;通過線程池創建線程。

其中前兩種方式線程執行完後都沒有返回值,後兩種是帶返回值的。


敘述

繼承Thread類創建線程

  Thread類本質上是實現了Runnable接口的一個實例,代表一個線程的實例。啓動線程的唯一方法就是通過Thread類的start()實例方法。start()方法是一個native方法,它將啓動一個新線程,並執行run()方法。這種方式實現多線程很簡單,通過自己的類直接extend Thread,並複寫run()方法,就可以啓動新線程並執行自己定義的run()方法。

public class ThreadDemo01 extends Thread{
    public ThreadDemo01(){
        //編寫子類的構造方法,可缺省
    }
    public void run(){
        //編寫自己的線程代碼
        System.out.println(Thread.currentThread().getName());
    }
    public static void main(String[] args){ 
        ThreadDemo01 threadDemo01 = new ThreadDemo01(); 
        threadDemo01.setName("我是自定義的線程1");
        threadDemo01.start();       
        System.out.println(Thread.currentThread().toString());  
    }
}

實現Runnable接口創建線程

  如果自己的類已經extends另一個類,就無法直接extends Thread,此時,可以實現一個Runnable接口。通過實現Runnable接口,實現run方法,接口的實現類的實例作爲Thread的target作爲參數傳入帶參的Thread構造函數,通過調用start()方法啓動線程。

public class MultiThread_Test {
    public static void main(String[] args) {
    // 爲了啓動MyRunnable,需要首先實例化一個Thread,並傳入自己的MyRunnable實例
        MyRunnable mr = new MyRunnable();
        new Thread(mr).start();
    }
}

public class MyRunnable implements Runnable {
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

實現Callable接口通過FutureTask包裝器來創建Thread線程

1.創建Callable接口的實現類 ,並實現Call方法

2.創建Callable實現類的實現,使用FutureTask類包裝Callable對象,該FutureTask對象封裝了Callable對象的Call方法的返回值

3.使用FutureTask對象作爲Thread對象的target創建並啓動線程

4.調用FutureTask對象的get()來獲取子線程執行結束的返回值


public class Tickets<Object> implements Callable<Object>{

    //重寫call方法
    @Override
    public Object call() throws Exception {
        // TODO Auto-generated method stub
        System.out.println(Thread.currentThread().getName()+"-->我是通過實現Callable接口通過FutureTask包裝器來實現的線程");
        return null;
    }  
 }
public class ThreadDemo03 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Callable<Object> oneCallable = new Tickets<Object>();
  
        //由Callable<Object>創建一個FutureTask<Object>對象:   
        FutureTask<Object> oneTask = new FutureTask<Object>(oneCallable);
     
        //由FutureTask<Object>創建一個Thread對象: 
        Thread t = new Thread(oneTask);

        System.out.println(Thread.currentThread().getName());

        t.start();

    }
}

使用線程池創建線程

結合線程池接口ExecutorService就可以實現傳說中有返回結果的多線程了。

public class ThreadDemo05{

    private static int POOL_NUM = 10;     //線程池數量

    /**
     * @param args
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        // 創建固定數目線程的線程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);  
        for(int i = 0; i<POOL_NUM; i++)  
        {  
            RunnableThread thread = new RunnableThread();

            //Thread.sleep(1000);
            // ExecutoreService提供了submit()方法,傳遞一個Callable,或Runnable,返回Future。如果Executor後臺線程池還沒有完成Callable的計算,這調用返回Future對象的get()方法,會阻塞直到計算完成。
            executorService.execute(thread);  
        }
        //關閉線程池
        executorService.shutdown(); 
    }   

}

public class RunnableThread implements Runnable  
{     
    @Override
    public void run()  
    {  
        System.out.println("通過線程池方式創建的線程:" + Thread.currentThread().getName() + " ");  

    }  
}  

小結

多線程的實現方式,在代碼中寫法千變萬化,但其本質是不變的。
感謝您的閱讀~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章