Skip to content

线程启动方法对比

结论

  1. 使用new Thread方式创建线程 调用run方法,在主线程中执行;调用start方法,在新线程中执行。
  2. 继承Thread,new 继承类方式创建线程 无论调用run方法还是start方法,均在新线程中执行。
  3. 实现Runnable接口,并实例化 调用run方法,在主线程中执行
  4. 实现Callable接口,并实例化 调用call方法,在主线程中执行
Method namenew Threadextend Threadimplements Runnableimplements Callable
start新线程新线程
run主线程新线程主线程
call主线程

验证代码

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

public class Test {

    public static class ExtendThread extends Thread {
        @Override
        public void run() {
            System.out.println("run" + this.getName() + this.getId());
        }

        @Override
        public void start() {
            System.out.println("start" + this.getName() + this.getId());
        }
    }

    public static class ImplementRunnable implements Runnable {

        private String name;
        private long id;

        public ImplementRunnable(String name, long id) {
            this.name = name;
            this.id = id;
        }

        @Override
        public void run() {
            System.out.println("run" + name + id + ":" + Thread.currentThread().getName() + Thread.currentThread().getId());
        }

    }

    public static class CallableThread implements Callable<String> {
        @Override
        public String call() throws Exception {
            return Thread.currentThread().getName() + Thread.currentThread().getId();
        }

    }

    public static void main(String[] args) throws Exception {
        // 打印主线程名称及ID
        System.out.println(Thread.currentThread().getName() + Thread.currentThread().getId());

        // 创建第一个线程类,先执行start再执行run
        ExtendThread extendThread1 = new ExtendThread();
        extendThread1.start();
        extendThread1.run();

        // 创建第二个线程类,先执行run再执行start 以排除先后执行顺序的影响
        ExtendThread extendThread2 = new ExtendThread();
        extendThread2.run();
        extendThread2.start();

        // 创建第一个Runnable接口实例,直接调用run方法
        ImplementRunnable implementRunnable1 = new ImplementRunnable("implementRunnable", 1L);
        implementRunnable1.run();

        // 创建第二个Runnable接口实例,放到Thread中,调用start方法
        ImplementRunnable implementRunnable2 = new ImplementRunnable("implementRunnable", 2L);
        new Thread(implementRunnable2).start();

        // 创建第三个Runnable接口实例,放到Thread中,调用start方法
        ImplementRunnable implementRunnable3 = new ImplementRunnable("implementRunnable", 3L);
        new Thread(implementRunnable3).run();

        // 创建第一个Callable接口示例,直接调用call方法
        CallableThread callableThread1 = new CallableThread();
        System.out.println("callableThread1.call()" + "\t\t" + callableThread1.call());

        // 创建第一个FutureTask示例,直接调用run方法
        FutureTask<String> futureTask = new FutureTask<>(new CallableThread());
        futureTask.run();
        System.out.println("futureTask.run()" + "\t\t" + futureTask.get());

        // 创建第二个FutureTask示例,放到Thread中,调用start方法
        futureTask = new FutureTask<>(new CallableThread());
        new Thread(futureTask).start();
        System.out.println("new Thread(futureTask).start()" + "\t\t" + futureTask.get());

        // 创建第三个FutureTask示例,放到Thread中,调用run方法
        futureTask = new FutureTask<>(new CallableThread());
        new Thread(futureTask).run();
        System.out.println("new Thread(futureTask).run()" + "\t\t" + futureTask.get());
    }
}

执行结果

Text
main1
startThread-012
runThread-012
runThread-113
startThread-113
runimplementRunnable1:main1
runimplementRunnable3:main1
runimplementRunnable2:Thread-214
futureTask.run()                        main1
new Thread(futureTask).start()                        Thread-416
new Thread(futureTask).run()                        main1