通常创建线程使用两种方式
1.继承Thread类,重写run方法
public class ThreadDemo extends Thread {@Override
public void run() {
System.out.println("创建线程方式1");
}public static void main(String[] args) {
ThreadDemo threadDemo = new ThreadDemo();
threadDemo.start();
}}
2.实现Runnable接口(Runnbale中只有一个run方法),重写run方法。然后把实例作为参数传入Thread的构造方法中
public class ThreadDemo implements Runnable {@Override
public void run() {
System.out.println("创建线程方式2");
}public static void main(String[] args) {
ThreadDemo threadDemo = new ThreadDemo();
//分析源码
new Thread(threadDemo).start();
}}
3.分析案例2中的源码得知
1.Thread实现了Runnable接口,重写了run方法
2.threadDemo在构造函数中作为参数传递给Thread中的target属性
3.当执行线程的run方法时,target(threadDemo)执行子类重写的run方法,实现业务逻辑
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
//只展示部分代码
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
SecurityManager security = System.getSecurityManager();
this.group = g;
this.priority = parent.getPriority();
**this.target = target;
**
}@Override
public void run() {
if (target != null) {
target.run();
}
}
无论哪种方式创建线程,本质都是实现了Runnable接口,重写了run方法。直接调用run方法不属于多线程
文章图片
Java线程的创建调用过程如上图所示。首先,Java线程的start方法会创建一个本地线程(通过调用JVM_StartThread),该线程的线程函数是定义在jvm.cpp中的thread_entry,由其再进一步调用run方法。可以看到Java线程的run方法和普通方法其实没有本质区别,直接调用run方法不会报错,但是却是在当前线程执行,而不会创建一个新的线程。
4.FutureTask,Callable,FutureTask也可以创建线程,并且可以获得返回值
文章图片
FutureTask实现了Runnable接口重写run方法,同时可以作为参数传入Thread的构造函数。实现了Future接口,可以通过get(),cancel()获取返回值,取消线程。
public class FutureTaskDemo implements Callable {@Override
public String call() throws Exception {
System.out.println("重写Callable中的call方法");
return "success";
}public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
FutureTask task = new FutureTask(new FutureTaskDemo());
new Thread(task).start();
//获取返回值
System.out.println(task.get());
}}
通过上面对Thread的分析大致, 在Thread中调用FutureTask的实例的run方法,然后run()中调用了Callable实例的call方法,执行业务逻辑。同时获取返回值。
【线程之Thread,Runnable,Callable】引用文章:https://segmentfault.com/a/11...
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)