创建线程的三种方式_Callable和Runnable的区别
2024-08-30 13:21:14
Java 提供了三种创建线程的方法
- 通过实现Runnable接口
- 通过继承Thread接口
- 通过Callable和Future创建线程
通过实现 Runnable 接口来创建线程
public class RunnableDemo {
public static void main(String[] args) {
new Thread(new MyThread(),"线程1").start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub }
},"线程2").start();
}
} /**
* 实现 Runnable 接口的线程类
*/
class MyThread implements Runnable{ /**
* 重写run方法
*/
@Override
public void run() {
// TODO Auto-generated method stub }
}
通过继承Thread类
public class ThreadDemo {
public static void main(String[] args) {
new MyThread().start();
new Thread(new MyThread(), "线程2").start();
}
}
class MyThread extends Thread{ /**
* 重写run方法
*/
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
}
}
通过Callable和Future创建线程
public class FutureDemo {
public static void main(String[] args) {
//创建 Callable 实现类的实例
MyCallable myCallable = new MyCallable();
//使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值
FutureTask<String> futureTask = new FutureTask<String>(myCallable);
String res = null;
try {
//使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程
//没这句,下句代码获取不到结果,会一直等待执行结果
new Thread(futureTask,"线程1").start();
//调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值
res = futureTask.get();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(res);
}
}
/**
* 创建 Callable 接口的实现类,并实现 call() 方法
*/
class MyCallable implements Callable<String>{ /**
* 该 call() 方法将作为线程执行体,并且有返回值
*/
@Override
public String call() throws Exception {
return "success";
}
}
Runnable和Callable的异同:
相同点:
- 两者都是接口;(废话)
- 两者都可用来编写多线程程序;
- 两者都需要调用Thread.start()启动线程;
不同点:
- 两者最大的不同点是:实现Callable接口的任务线程能返回执行结果;而实现Runnable接口的任务线程不能返回结果;
- Callable接口的call()方法允许抛出异常;而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛;
注意点:
- Callable接口支持返回执行结果,此时需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取‘将来’结果;当不调用此方法时,主线程不会阻塞!
Callable的优势
多线程返回执行结果是很有用的一个特性,因为多线程相比单线程更难、更复杂的一个重要原因就是因为多线程充满着未知性,某条线程是否执行了?某条线程执行了多久?某条线程执行的时候我们期望的数据是否已经赋值完毕?无法得知,我们能做的只是等待这条多线程的任务执行完毕而已。而Callable+Future/FutureTask却可以获取多线程运行的结果,可以在等待时间太长没获取到需要的数据的情况下取消该线程的任务,真的是非常有用。
最新文章
- Jenkins xcodebuild There are no schemes in workspace
- 【转】Quartus II调用modelsim无缝仿真
- c++基础(一):数据类型和结构
- android应用程序的安装方式与原理
- VMware Workstation CentOS-6.4-x86_64-minimal 配置网络以及安装JDK和tomcat
- Linux下安装MySQL5.6
- Windows Live Writer的Markdown插件MarkdownInLiveWriter支持语法高亮了
- 自动生成 Lambda查询和排序,从些查询列表so easy
- HDU 1870 愚人节的礼物
- Servlet的学习之ServletContext(2)
- 华为C8816电信版ROOT过程
- 结合jenkins在Linux服务器搭建测试环境
- 深入解读Resnet
- cmder中文乱码、文字重叠等问题
- C#几个经常用到的字符串的截取
- 解决mysql连接linux上mysql服务器的问题
- (原)关于ffmpeg使用custom io-context遇到的一些坑
- Unity Shader 矩阵基本信息
- qt 软件打包
- Shell脚本 | 抓取log文件
热门文章
- javascript break 和continue
- 879C
- java利用Aspose.words.jar将本地word文档转化成pdf(完美破解版 无水印 无中文乱码)
- 2.28 MapReduce在实际应用中常见的优化
- 洛谷 - P1337 - 平衡点/吊打XXX
- C#中,用HashTable,DataTable等复制和克隆浅谈
- AForge.net简介和认识
- stylus基础教程,stylus实例教程,stylus语法总结
- WOW.js 动画使用
- Easy Game LightOJ - 1031