DarkHorse_pxf

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

统计

【Thinking in Java】Java Callable的使用

  Callable<>和Runable类似,都是用于Java的并发执行。

  唯一的区别是,Runable的run方法的返回是void,而Callable的call方法是有返回值的

  call方法返回的类型是实现Callable<?>泛型接口时所指定的类型,不然会编译出错。

  那么,怎样获取call方法的返回值呢?——通过执行Callable,可以返回的Future对象,通过调用future对象的get方法来获取call方法的返回值。

  综上,你把Callable当成是有返回值的Runable就行了,只不过Callable的是call,Runable的是run。

  下面是演示代码:

复制代码
 1 import java.util.ArrayList;
 2 import java.util.concurrent.Callable;
 3 import java.util.concurrent.ExecutionException;
 4 import java.util.concurrent.ExecutorService;
 5 import java.util.concurrent.Executors;
 6 import java.util.concurrent.Future;
 7 
 8 
 9 public class CallableTest{
10     public static void main(String[] args) {
11         ExecutorService executorService=    //创建线程池
12                 Executors.newCachedThreadPool();
13         ArrayList<Future<String>> list=
14                 new ArrayList<Future<String>>();
15         for (int i = 0; i < 10; i++) {
16             list.add(executorService    //通过submit方法来提交Callable到线程池中执行
17                     .submit(new TaskWithResult()));
18         }
19         for (Future<String> future : list) {
20             try {
21                 System.out.println(future.get()); //通过get方法来获取call返回值
22             } catch (InterruptedException e) {
23                 e.printStackTrace();
24             } catch (ExecutionException e) {
25                 e.printStackTrace();
26             }
27         }
28     }
29 
30     
31     static class TaskWithResult implements Callable<String>{
32         private static int taskNum=0;
33         private int taskId=taskNum;
34         public TaskWithResult() {
35             taskNum++;
36         }
37 
38         @Override
39         public String call() throws Exception {
40             try {
41                 Thread.sleep(this.taskId*1000);    //我制造的时间差,更直观地显示call和run方法的相似性。
42             } catch (InterruptedException e) {
43                 e.printStackTrace();
44             }
45             return "Result of TaskWithResult: "+this.taskId;
46         }
47         
48     } 
49 
50 }
复制代码

 

  运行结果:

  Result of TaskWithResult: 0
  Result of TaskWithResult: 1
  Result of TaskWithResult: 2
  Result of TaskWithResult: 3
  Result of TaskWithResult: 4
  Result of TaskWithResult: 5
  Result of TaskWithResult: 6
  Result of TaskWithResult: 7
  Result of TaskWithResult: 8
  Result of TaskWithResult: 9

  以上的运行结果是每隔一秒打印一行的,这说明,call和run是差不多的。

  

posted on   DarkHorse_pxf  阅读(387)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
点击右上角即可分享
微信分享提示