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"); } }
|
