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接口方式来创建线程.

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