实现Callable接口创建线程

Callable|Runnable

注意:

  • java对线程的抽象只有Thread类,只有创建Thread类对象或者其子类对象才能实现线程的创建,所以本质上讲java中只有一种创建线程的方法。
  • 但是从创建线程的形式上讲,继承Thread类,实现Runnable接口或者实现Callable接口等等这些方式可以实现线程的创建,它们之间一些差别,适用于不同的场景。
  • 实现Runnable接口和实现Callable接口方式创建线程本质上的区别是前者无返回值,后者有返回值。

Callable实例代码

Callable实现类得依赖FutureTask类来实现其功能:

一个Demo例子,我们使用多个线程分别去统计本地各个磁盘的容量,最后汇总得出所有磁盘的总容量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Demo01FutureTask {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//使用多个线程分别去统计各个磁盘的容量,然后计算总和
String[] arr = {"C:\\","D:\\","E:\\","F:\\","G:\\"};
FutureTask<Long>[] futureTasks = new FutureTask[arr.length];
int index = 0;

// 创建多个线程去执行
for (String s : arr) {
FutureTask<Long> ft = new FutureTask<>(new Callable<Long>() {
@Override
public Long call() throws Exception {
File file = new File(s);
long start = System.nanoTime();
long size = file.getTotalSpace();
long end = System.nanoTime();

System.out.println(s+" "+size/(1024*1024)+"M" + "-----耗时" + (end - start) + "ns");
return size;
}
});
futureTasks[index++] = ft;
new Thread(ft).start();
}

// 计算结果
long sum = 0;
for (FutureTask<Long> futureTask : futureTasks) {
sum += futureTask.get();
}
System.out.println("几个磁盘的容量总和:" + sum/(1024*1024) + " M");
}
}

使用线程池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Demo02Future {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//使用多个线程分别去统计各个磁盘的容量,然后计算总和
String[] arr = {"C:\\","D:\\","E:\\","F:\\","G:\\"};
Future<Long>[] futures = new Future[arr.length];
int index = 0;

// 使用线程池创建多个线程去执行
ExecutorService executorService = Executors.newCachedThreadPool();
for (String s : arr) {
// 提交给线程池
Future<Long> future = executorService.submit(new Callable<Long>() {
@Override
public Long call() throws Exception {
File file = new File(s);
long start = System.nanoTime();
long size = file.getTotalSpace();
long end = System.nanoTime();

System.out.println(s+" "+size/(1024*1024)+"M" + "-----耗时" + (end - start) + "ns");
return size;
}
});
// 记录
futures[index++] = future;
}

// 计算结果
long sum = 0;
for (Future<Long> future : futures) {
sum += future.get();
}
System.out.println("几个磁盘的容量总和:" + sum/(1024*1024) + " M");
}
}


实现Callable接口创建线程
https://blog.wangxk.cc/2020/10/06/实现Callable接口创建线程/
作者
Mike
发布于
2020年10月6日
许可协议