Java 多线程中 Thread、Runnable 和 FutureTask 比较

1. 用 Thread 创建一个线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ThreadTest {
public static class MyThread extends Thread {
@Override
public void run() {
Thread.sleep(100);
System.out.println("Hello world");
}
}

public static void main(String[] args) {
// 创建线程
MyThread myThread = new MyThread();
// 启动线程
myThread.start();
System.out.println("Main");
}
}
  • 可以直接使用 this 获取当前线程
  • Java 不支持多继承, 如果继承了 Thread 就不能继承其他类了
  • 任务与代码没有分离, 如果多个线程执行一样的任务时需要多份任务代码
  • 没有返回值
2. 用 Runnable 创建一个线程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class RunAbleTask implements Runnable {
@Override
public void run() {
Thread.sleep(100);
System.out.println("Hello World");
}

public static void main(String[] args) {
// 创建任务
RunAbleTask runAbleTask = new RunAbleTask();
// 启动任务
new Thread(runAbleTask).start();
new Thread(runAbleTask).start();
System.out.println("Main");
}
}
  • 多个线程可以共享一份 task 代码逻辑
  • RunAbleTask 可以继承其他类
  • 没有返回值
3. 用 FutureTask 创建一个线程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class CallerTask implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(100);
return "Hello World";
}

public static void main(String[] args) {
// 创建异步任务
// FutureTask<String> futureTask = new FutureTask<>(() -> "Hello World");
FutureTask<String> futureTask = new FutureTask<>(new CallerTask());
// 启动多线程
new Thread(futureTask).start();
// 等待任务执行完毕
String result = null;
try {
result = futureTask.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
System.out.println(result);
System.out.println("Main");
}
}
  • 多个线程可以共享一份 task 代码逻辑
  • FutureTask 可以继承其他类
  • 有返回值
  • 主线程会堵塞

总结

特性 Thread Runable FutureTask
是否能继承其他类 不能
共享任务代码 不能
有返回值 没有 没有
会堵塞主线程 不会 不会
作者

坑 飞

发布于

2019-12-01

更新于

2021-09-06

许可协议

评论