当前位置:网站首页>Callable实现多线程
Callable实现多线程
2022-08-11 03:50:00 【初夏0811】
1.Callable和Runnable
先看一下两个接口的定义:
Callable:
public interface Callable<V> {
V call() throws Exception;
}
Runnable:
interface Runnable {
public abstract void run();
}
明显能看到区别:
1.Callable能接受一个泛型,然后在call方法中返回一个这个类型的值。而Runnable的run方法没有返回值
2.Callable的call方法可以抛出异常,而Runnable的run方法不会抛出异常。
Future
返回值Future也是一个接口,通过他可以获得任务执行的返回值。
定义如下:
public interface Future<V> {
boolean cancel(boolean var1);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long var1, TimeUnit var3) throws InterruptedException, ExecutionException, TimeoutException;
}
其中的get方法获取的就是返回值。
下面看下提交一个任务的场景:
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(2);
//创建一个Callable,3秒后返回String类型
Callable myCallable = new Callable() {
@Override
public String call() throws Exception {
Thread.sleep(3000);
System.out.println("calld方法执行了");
return "call方法返回值";
}
};
System.out.println("提交任务之前 "+getStringDate());
Future future = executor.submit(myCallable);
System.out.println("提交任务之后,获取结果之前 "+getStringDate());
System.out.println("获取返回值: "+future.get());
System.out.println("获取到结果之后 "+getStringDate());
}
public static String getStringDate() {
Date currentTime = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
String dateString = formatter.format(currentTime);
return dateString;
}
}
通过executor.submit提交一个Callable,返回一个Future,然后通过这个Future的get方法取得返回值。
运行结果如下:
提交任务之前 12:13:01
提交任务之后,获取结果之前 12:13:01
calld方法执行了
获取返回值: call方法返回值
获取到结果之后 12:13:04
get()方法的阻塞性
通过上面的输出可以看到,在调用submit提交任务之后,主线程本来是继续运行了。但是运行到future.get()的时候就阻塞住了,一直等到任务执行完毕,拿到了返回的返回值,主线程才会继续运行。
这里注意一下,他的阻塞性是因为调用get()方法时,任务还没有执行完,所以会一直等到任务完成,形成了阻塞。
任务是在调用submit方法时就开始执行了,如果在调用get()方法时,任务已经执行完毕,那么就不会造成阻塞。
下面在调用方法前先睡4秒,这时就能马上得到返回值。
System.out.println("提交任务之前 "+getStringDate());
Future future = executor.submit(myCallable);
System.out.println("提交任务之后 "+getStringDate());
Thread.sleep(4000);
System.out.println("已经睡了4秒,开始获取结果 "+getStringDate());
System.out.println("获取返回值: "+future.get());
System.out.println("获取到结果之后 "+getStringDate());
运行如下:
提交任务之前 12:36:04
提交任务之后 12:36:04
calld方法执行了
已经睡了4秒,开始获取结果 12:36:08
获取返回值: call方法返回值
获取到结果之后 12:36:08
可以看到吗,因为睡了4秒,任务已经执行完毕,所以get方法立马就得到了结果。
同样的原因,submit两个任务时,总阻塞时间是最长的那个。
下面看下有多个个任务,一个3秒,一个5秒。
Callable myCallable = new Callable() {
@Override
public String call() throws Exception {
Thread.sleep(5000);
System.out.println("calld方法执行了");
return "call方法返回值";
}
};
Callable myCallable2 = new Callable() {
@Override
public String call() throws Exception {
Thread.sleep(3000);
System.out.println("calld2方法执行了");
return "call2方法返回值";
}
};
System.out.println("提交任务之前 "+getStringDate());
Future future = executor.submit(myCallable);
Future future2 = executor.submit(myCallable2);
System.out.println("提交任务之后 "+getStringDate());
System.out.println("开始获取第一个返回值 "+getStringDate());
System.out.println("获取返回值: "+future.get());
System.out.println("获取第一个返回值结束,开始获取第二个返回值 "+getStringDate());
System.out.println("获取返回值2: "+future2.get());
System.out.println("获取第二个返回值结束 "+getStringDate());
提交任务之前 14:14:47
提交任务之后 14:14:48
开始获取第一个返回值 14:14:48
calld2方法执行了
calld方法执行了
获取返回值: call方法返回值
获取第一个返回值结束,开始获取第二个返回值 14:14:53
获取返回值2: call2方法返回值
获取第二个返回值结束 14:14:53
获取第一个结果阻塞了5秒,所以获取第二个结果立马就得到了。
边栏推荐
- Paper Accuracy - 2017 CVPR "High-Resolution Image Inpainting using Multi-Scale Neural Patch Synthesis"
- Detailed explanation of VIT source code
- 互换性测量与技术——偏差与公差的计算,公差图的绘制,配合与公差等级的选择方法
- AI + medical: for medical image recognition using neural network analysis
- MYSQLg advanced ------ clustered and non-clustered indexes
- Binary tree related code questions [more complete] C language
- Leetcode 669. 修剪二叉搜索树
- FTP错误代码列表
- What kind of programming trading strategy types can be divided into?
- A brief analysis of whether programmatic futures trading or manual order is better?
猜你喜欢
A simple JVM tuning, learn to write it on your resume
互换性测量技术-几何误差
EasyCVR接入GB28181设备时,设备接入正常但视频无法播放是什么原因?
Power Cabinet Data Monitoring RTU
机器学习中什么是集成学习?
Qnet Weak Network Test Tool Operation Guide
【FPGA】SDRAM
一文读懂 高性能可预期数据中心网络
云平台下ESB产品开发步骤说明
The last update time of the tables queried by the two nodes of the rac standby database is inconsistent
随机推荐
EasyCVR接入GB28181设备时,设备接入正常但视频无法播放是什么原因?
App Basic Framework Construction丨Log Management - KLog
MYSQLg高级------回表
【FPGA】abbreviation
作业8.10 TFTP协议 下载功能
Interchangeability and Measurement Technology—Surface Roughness Selection and Marking Method
Unity2D animation (1) introduction to Unity scheme - animation system composition and the function of use
树莓派入门(5)系统备份
When EasyCVR is connected to the GB28181 device, what is the reason that the device is connected normally but the video cannot be played?
没想到MySQL还会问这些...
Detailed explanation of VIT source code
LeetCode刷题第16天之《239滑动窗口最大值》
轮转数组问题:如何实现数组“整体逆序,内部有序”?“三步转换法”妙转数组
论文精度 —— 2017 CVPR《High-Resolution Image Inpainting using Multi-Scale Neural Patch Synthesis》
DNS separation resolution and intelligent resolution
LeetCode热题(12.买卖股票的最佳时机)
A brief analysis of whether programmatic futures trading or manual order is better?
荣威imax8ev魔方电池安全感,背后隐藏着哪些黑化膨胀?
图解LeetCode——640. 求解方程(难度:中等)
Uni - app - access to Chinese characters, pinyin initials (according to the Chinese get pinyin initials)