线程启动方法对比
结论
- 使用new Thread方式创建线程 调用run方法,在主线程中执行;调用start方法,在新线程中执行。
- 继承Thread,new 继承类方式创建线程 无论调用run方法还是start方法,均在新线程中执行。
- 实现Runnable接口,并实例化 调用run方法,在主线程中执行
- 实现Callable接口,并实例化 调用call方法,在主线程中执行
Method name | new Thread | extend Thread | implements Runnable | implements 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