【jdk源码分析】java多线程开启的三种方式
1、继承Thread类,新建一个当前类对象,并且运行其start()方法
package com.xiaostudy.thread; /**
* @desc 第一种开启线程的方式
* @author xiaostudy
*
*/
public class Demo1_Thread extends Thread { public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " run()...");
}
} public static void main(String[] args) {
Demo1_Thread demo = new Demo1_Thread();
demo.start();
for (int i = 0; i < 10; i++) {
System.out.println(i + " main()...");
}
} }
Demo1_Thread.java

上面这里就是当前类的一个线程和main线程一起运行
2、实现Runnable接口,然后新建当前类对象,接着新建Thread对象时把当前类对象传进去,最后运行Thread对象的start()方法
package com.xiaostudy.thread; /**
* @desc 第二种开启线程的方式
* @author xiaostudy
*
*/
public class Demo2_Thread implements Runnable { public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " run()...");
}
} public static void main(String[] args) {
Demo2_Thread demo = new Demo2_Thread();
Thread thread = new Thread(demo);
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println(i + " main()...");
}
} }
Demo2_Thread.java

分析:
从Thread的有参构造方法进去

当前类传进去,进入到Thread的init()方法

再跟进去

下面截图问题,分开两个,看行号。就把当前类赋值给了Thread的target属性


再回过头来看Thread对象的run()方法,因为当Thread对象的start()方法调用时,是执行Thread对象的run()方法(这里就不深入分析)

这里的target的值就是当前类对象,所以最后还是执行了当前类对象的run()方法

3、实现Callable接口,新建当前类对象,在新建FutureTask类对象时传入当前类对象,接着新建Thread类对象时传入FutureTask类对象,最后运行Thread对象的start()方法
package com.xiaostudy.thread; import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask; /**
* @desc 第三种开启线程的方式
* @author xiaostudy
*
*/
public class Demo3_Thread implements Callable { public static void main(String[] args) {
Callable callable = new Demo3_Thread();
FutureTask futureTask = new FutureTask(callable);
Thread thread = new Thread(futureTask);
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println(i + " main()...");
}
} public Object call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println(i + " call()...");
}
return null;
} }
Demo3_Thread.java

分析:
同样从Thread的有参构造方法进去

同样也是跟第二种方法一样

那么,就看Runnable接口和FutureTask类的关系。从下面的图看出FutureTask类是Runnable接口的继承接口的实现类。

接着看看FutureTask的有参构造

从下图可以看出,FutureTask的有参构造,把当前类对象传给了FutureTask的callable属性

那么当Thread执行start()方法时,就是执行FutureTask的run()方法,从下面图看到,最后就是执行了当前类的call()方法


【jdk源码分析】java多线程开启的三种方式的更多相关文章
- 如何实现有返回值的多线程 JAVA多线程实现的三种方式
可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口.执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable ...
- JDK源码分析之concurrent包(三) -- Future方式的实现
上一篇我们基于JDK的源码对线程池ThreadPoolExecutor的实现做了分析,本篇来对Executor框架中另一种典型用法Future方式做源码解读.我们知道Future方式实现了带有返回值的 ...
- JAVA多线程实现的三种方式
JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...
- AJPFX关于JAVA多线程实现的三种方式
JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...
- jdk源码分析——java.lang.Boolean
1.Boolean类里面的2个静态变量. Boolean类,直接声明了2个静态变量,TRUE 和 FALSE,指向2个对象. public static final Boolean TRU ...
- JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue
JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue 目的:本文通过分析JDK源码来对比ArrayBlockingQueue 和LinkedBlocki ...
- JDK源码分析(2)LinkedList
JDK版本 LinkedList简介 LinkedList 是一个继承于AbstractSequentialList的双向链表.它也可以被当作堆栈.队列或双端队列进行操作. LinkedList 实现 ...
- 【JDK】JDK源码分析-ArrayList
概述 ArrayList 是 List 接口的一个实现类,也是 Java 中最常用的容器实现类之一,可以把它理解为「可变数组」. 我们知道,Java 中的数组初始化时需要指定长度,而且指定后不能改变. ...
- JDK 源码分析(4)—— HashMap/LinkedHashMap/Hashtable
JDK 源码分析(4)-- HashMap/LinkedHashMap/Hashtable HashMap HashMap采用的是哈希算法+链表冲突解决,table的大小永远为2次幂,因为在初始化的时 ...
随机推荐
- 购物车删除商品,总价变化 innerHTML = ''并没有删除节点,内容仍存在
w元素的上的下. function deleteLi(tmpId) { //document.getElementById(tmpId).innerHTML = ''; var wdel = docu ...
- Linux系统CPU核数等信息查看
版权声明:本文为原创文章,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明. https://blog.csdn.net/fgf00/article/details/52584 ...
- SpringCloud 进阶之Eureka(服务注册和发现)
1. Eureka 服务注册与发现 Eureka 是一个基于REST的服务,用于服务的的注册与发现; Eureka采用C-S的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册 ...
- SVN部署
1.安装SVN yum install subversion –y 2.配置SVN 建立SVN版本库数据存储目录(svndata)及用户.密码权限目录(svnpasswd) mkdir -p /app ...
- MySQL的表分区详解 - 查看分区数据量,查看全库数据量----转http://blog.csdn.net/xj626852095/article/details/51245844
查看分区数据量,查看全库数据量 USE information_schema; SELECT PARTITION_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA.PAR ...
- Linux命令(1)——xargs命令
1.功能: xargs能够将stdin中以空格或换行符进行分隔的数据.形成以空格分隔的參数(arguments),传递给其它命令.由于以空格作为分隔符,所以有一些文件名称或者其它意义的名词内含有空格的 ...
- Python:解析properties文件
在项目中遇到解析properties的情况,而Python中正好没有解析properties文件的现成模块,于是从网上找到了这个脚本,有一些小地方修改了一下 原博客: Python读写properti ...
- jQuery中on()方法用法实例
这篇文章主要介绍了jQuery中on()方法用法,实例分析了on()方法的功能.定义及在匹配元素上绑定一个或者多个事件处理函数的使用技巧,需要的朋友可以参考下 本文实例讲述了jQuery中on()方法 ...
- SIP UserAgent (B2BUA client)——pjsip
SIP UserAgent常用的SIP协议栈有pjsip/bell-sip/sofia-sip/libeXosip/libre等 https://github.com/staskobzar/sip_s ...
- 记CM+kerberos环境停电后无法启动报错An error: (java.security.PrivilegedActionException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism leve
公司突然停电,然后cm环境无法重启,报错 An error: (java.security.PrivilegedActionException: javax.security.sasl.SaslExc ...