java創建線程的三種方式

一. 類繼承Thread類創建線程

/**
 *繼承Thread類創建線程的方式
 */
public class MyThreadExtendThread extends  Thread{
    private int i;

    //重寫Thread的run方法來創建用戶線程類的執行體
    @Override
    public void run() {
        //迭代輸出0到100的數字
        for(;i<100;i++){
            System.out.println(getName()+" "+i);
        }
    }

    //main主線程
    public static void  main(String[] args){
        for (int i=0;i<100;i++){
            //非直接繼承類的線程獲得線程name需要使用Thread.currentThread().getName()
            System.out.println(Thread.currentThread().getName()+" "+i);
            if (i==20){
                //創建第一個用戶線程,start()啓動線程
                new  MyThreadExtendThread().start();
                //創建第二個用戶線程,start()啓動線程
                new  MyThreadExtendThread().start();
            }
        }
    }
}

二. 實現runnable接口創建線程

/**
 * 實現runnable接口創建線程
 * Created by jeker on 17-6-25.
 */
public class MyThreadImplementRunable implements  Runnable {

    private int i;

    //實現Runnable接口的run()方法來創建用戶線程的執行體
    @Override
    public void run() {
        //迭代輸出0到100的數字
        for (;i<100;i++){
            System.out.println(Thread.currentThread().getName()+" "+i);
        }
    }

    //main主線程
    public static void main(String[] args){
        for (int i =0 ;i<100;i++){
            System.out.println(Thread.currentThread().getName()+" "+i);
            if (i==20){
                //創建用戶線程類實例
                MyThreadImplementRunable myThreadImplementRunable = new MyThreadImplementRunable();
                //以用戶線程類的實例作爲Thread的target來創建thrad對象,並制定線程名稱,即線程對象
                new Thread(myThreadImplementRunable,"線程1").start();
                new Thread(myThreadImplementRunable,"線程2").start();
            }
        }
    }
}


三.使用callable和future來創建線程

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * 使用callable和future創建線程(使線程執行後可以有返回值)
 * Created by jeker on 17-6-25.
 */
public class CallableAndFuture {
    //main主線程
    public static void main(String[] args) {
        //創建用戶callable線程類,並實現實現callable方法
        Callable<Integer> callable = new Callable<Integer>() {
            //實現callable接口的call方法,來創建用戶線程的執行體,並返回相應類型的值
            @Override
            public Integer call() throws Exception {
                int i;
                for (i = 0; i < 100; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                }
                return i;
            }
        };

        //使用futureTask對象來包裝callable對象,該futureTask對象封裝了callable的返回值
        FutureTask<Integer> futureTask = new FutureTask<Integer>(callable);
        for (int i = 0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+" "+i);
            if (i==20){
                //使用future作爲thread的target來創建線程,實質上還是以callable來創建線程的
                new Thread(futureTask,"futureTask1").start();
            }
        }
        try {
            //獲取線程的返回值通過futuretask類
            System.out.println("callable的返回值爲:"+futureTask.get());
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }

}

三種創建線程方式的對比:

使用方式一:

優點:簡單方便,獲取線程信息不需要使用Thread.CurrentThread.getName(),可以直接以this.getName的方式獲取.*
缺點:直接繼承了Thread類,無法再繼承其他類,擴展性差*

使用方式二:

優點:比較簡潔,可以另外繼承其他類擴展性好,同一個target創建的多個線程執行體共享一個成員變量.
缺點:獲取線程相關信息的時候需要使用Thread.CurrentThread.getName().

使用方式三:

優點:線程執行體可以有返回值,可以另外繼承其他類擴展性好,同一個target創建的多個線程執行體共享一個成員變量.
缺點:獲取線程相關信息的時候需要使用Thread.CurrentThread.getName().

綜上所述,推薦使用實現callable或runnable接口方式來創建線程.

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