Java 中有三种线程创建方式:
- 实现 Runnable 接口的 run 方法
- 继承 Thread 类并重写 run 的方法
- 实现 Callable接口,使用 FutureTask 方式。
首先看继承 Thread 类方式的实现。
public class ThreadTest {//继承 Thread 类并重写 run 方法public static class MyThread extends Thread {@Overridepublic void run() {System.out.println(「I am a child thread」);}}public static void main(String[] args) {// 创建线程MyThread thread = new MyThread();// 启动线程thread.start();}}
使用继承方式的好处是,在 run()方法内获取当前线程直接使用 this 就可以了,无须使用 Thread.currentThread()方法;而如果使用 Runnable 方式,则只能使用主线程里面被声明为 final 的变量。
不好的地方是 Java 不支持多继承,如果继承了 Thread 类,那么就不能再继承其他类。另外任务与代码没有分离,当多个线程执行一样的任务时需要多份任务代码,而 Runable 则没有这个限制。
下面看实现 Runnable 接口的 run 方法方式。
public static class RunableTask implements Runnable{@Overridepublic void run() {System.out.println("I am a child thread");}}public static void main(String[] args) throws InterruptedException{RunableTask task = new RunableTask();new Thread(task).start();new Thread(task).start();}
但是上面介绍的两种方式都有一个缺点,就是任务没有返回值。下面看最后一种,即使用 FutureTask 的方式。
//创建任务类,类似 Runable
public static class CallerTask implements Callable<String>{
@Override
public String call() throws Exception {
return 「hello」;
}
}
public static void main(String[] args) throws InterruptedException {
// 创建异步任务
FutureTask<String> futureTask = new FutureTask<>(new CallerTask());
//启动线程
new Thread(futureTask).start();
try {
//等待任务执行完毕,并返回结果
String result = futureTask.get();
System.out.println(result);
} catch (ExecutionException e) {
e.printStackTrace();
}
}
