从我实习面试开始就有在面试中遇到过这个问题:创建线程有几种方法
记得当时的回答是:在jdk1.5之后有三种创建方式
1.继承Thread类
2.实现Runnable接口
3.实现Callable接口
工作之后回顾这个问题就会想到,这三种方式的不同点在哪呢?所有有了探究的这篇文章
虽然网上已经有很多文章珠玉在前,但是我还是想写一篇我自己的文章,如果写的不好,请见谅
先来实现最基本的创建线程的三种方式吧
1.继承Thread类
/**
* @author miao
*/
public class ThreadDemo extends Thread {
private final String threadName;
public ThreadDemo(String threadName) {
this.threadName = threadName;
}
@Override
public void run() {
System.out.println(threadName + Thread.currentThread().getName());
}
public static void main(String[] args) {
// 多线程级别调用
new ThreadDemo("test thread demo:").start();
// 方法级别的调用
new ThreadDemo("test thread demo:").run();
}
}
2.实现Runnable接口
/**
* @author miao
*/
public class RunnableDemo implements Runnable {
@Override
public void run() {
System.out.println("RunnableDemo:" + Thread.currentThread().getName());
}
public static void main(String[] args) {
Thread thread = new Thread(new RunnableDemo());
thread.start();
}
}
3.实现Callable接口
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* @author miao
*/
public class FutureTaskDemo implements Callable<String> {
@Override
public String call() throws Exception {
return "return callable demo";
}
public static void main(String[] args) throws Exception {
FutureTask task = new FutureTask(new FutureTaskDemo());
new Thread(task).start();
System.out.println(task.get());
}
}
已经完成了三种创建线程的方式了,那么我们就来思考一下这三种方式的相同点和不同点吧
其实关于最常见面试题的就是:Runnable与Callable的不同点是什么?
一般同学会回答:Runnable无返回值,而Callable有返回值能抛异常
其实,这三种创建线程的方式本质上是一样的!!!!不信的话看我证明吧
首先是第一种方式,继承Thread
类,点开这个类我们可以看到,其实Thread
实现了Runnable
接口,重写了run()
方法