实现Runnable接口方式
package com.roocon.thread.t2;
public class Demo2 implements Runnable {
@Override
public void run() {
while(true){
System.out.println("thread running...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread thread = new Thread(new Demo2());
thread.start();
}
}
输出结果:
thread running...
thread running...
thread running...
thread running...
源码解读:
1.Thread类:根据以下代码知道,我们传入的runnable参数最后是赋值给了Thread类的属性target。
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null);
}
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name.toCharArray();
Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
/* Determine if it's an applet or not */
/* If there is a security manager, ask the security manager
what to do. */
if (security != null) {
g = security.getThreadGroup();
}
/* If the security doesn't have a strong opinion of the matter
use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
}
/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
g.checkAccess();
/*
* Do we have the required permissions?
*/
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
g.addUnstarted();
this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
if (security == null || isCCLOverridden(parent.getClass()))
this.contextClassLoader = parent.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext =
acc != null ? acc : AccessController.getContext();
this.target = target;//赋给了Thread的属性target
setPriority(priority);
if (parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
/* Set thread ID */
tid = nextThreadID();
}
2.调用start方法启动线程
thread.start();
3.Thread类就去找run方法:
@Override
public void run() {
if (target != null) {
target.run();
}
}
4.于是,调用了我们runnable接口中重写的run方法。输出:
thread running...
thread running...
thread running...
thread running...
实现Runnable接口方式的更多相关文章
- 03_线程的创建和启动_实现Runnable接口方式
[线程的创建和启动的步骤(实现Runnable接口方式)] 1.定义Runnable接口的实现类,并重写其中的run方法.run()方法的方法体是线程执行体. class SonThread imp ...
- java多线程--实现Runnable接口方式
因为java类只能继承一个类可以实现多个接口的特性,所以一般情况下不推荐使用继承Thread类实现多线程,下面是实现Runnable接口方式的简单多线程代码 package text; /** * 多 ...
- Java8使用实现Runnable接口方式创建新线程的方法
环境介绍 JDK版本:1.8 开发架构:spring boot 2.x 日志:slf4j 实现步骤 Runnable接口中只有一个run()方法,它是非Thread类子类的类提供的一种激活方式.一个类 ...
- 多线程实现方式---实现Runnable接口
多线程实现方式---实现Runnable接口 一个类如果需要具备多线程的能力,也可以通过实现java.lang.Runnable接口进行实现.按照Java语言的语法,一个类可以实现任意多个接口,所以该 ...
- java基础知识回顾之java Thread类--java线程实现常见的两种方式实现Runnable接口(二)
创建线程的第二中方式: /** * 步骤: 1定义类实现Runnable接口 2.实现Runnable接口中的run方法. 3.通过Thread类建立线程对象,并将Run ...
- 创建线程的两种方式:继承Thread类和实现Runnable接口
第一种方式:继承Thread类 步骤:1.定义类继承Thread 2.覆写Threa类的run方法. 自定义代码放在run方法中,让线程运行 3.调用线程的star方法, 该线程有两个作用:启动线程, ...
- 创建线程的一般方式和匿名内部类方式对比——实现runnable接口,重新run方法
启动:使用静态代理设计模式 优点:可同时实现继承,避免单继承局限性 一般方式: Programer.java /** * 真实角色 * * @author :liuqi * @date :2018-0 ...
- 创建多线程的方式:继承Thread类和实现Runnable接口
1.通过继承Thread类的方式创建多线程(这里只是简单的代码演示创建多线程的方法) package com.baozi.exer; public class ThreadDemo { public ...
- 几种创建线程方式Thread类和Runnable接口
对于很多想学习java的人来说,经常听别人说线程难,其实真正理解了线程后,一点都不会觉得线程难,这里我为大家梳理下线程的创建方式吧. 一.线程的创建方式有三种 1.继承Thread类 2.实现Runn ...
随机推荐
- 【转载】C#使用as关键字将对象转换为指定类型
在C#的编程开发过程中,很多时候涉及到数据类型的转换,可使用强制转换的方式,不过强制转换数据类型有时候会抛出程序异常错误,可以使用as关键字来进行类型的转换,如果转换成功将返回转换后的对象,如果转换不 ...
- iOS音频学习笔记一:常见音频封装格式及编码格式
(1) pcm格式 pcm是经过话筒录音后直接得到的未经压缩的数据流 数据大小=采样频率*采样位数*声道*秒数/8 采样频率一般是22k或者44k,位数一般是8位或者16位,声道一 ...
- 【charlse】charlse功能
(一)主界面介绍 一.工具导航栏 Charles 顶部为菜单导航栏,菜单导航栏下面为工具导航栏.视图如下图所示: 工具导航栏中提供了几种常用工具: :清除捕获到的所有请求 :红点状态说明正在捕获请 ...
- python urllib应用
urlopen 爬取网页 爬取网页 read() 读取内容 read() , readline() ,readlines() , fileno() , close() :这些方法的使用方式与文件对象完 ...
- mamcached+(magent+keepalived高可用)搭建及理论概述
目录 一.理论概述 工作流程 二.部署 环境 环境概述 部署 三.测试 四.总结 一.理论概述 Memcached服务器端与PHP-Memcache客户端安装配置_服务器应用_Linux公社-Linu ...
- 【nodejs代理服务器二】nodejs webpack打包配置踩坑总结
接着上篇用Nodejs开发web代理,防止web渗透.如果部署到正式环境,需要进行打包配置. 我在用webpack打包配置中遇到了几个错误,总结如下: webpack环境变量问题 https://ww ...
- Centos7.6进入挂载硬盘后,进入应急模式(emergency mode)而非图形模式解决方法
Centos7.6进入挂载硬盘后,进入应急模式(emergency mode)而非图形模式解决方法 话说某天我想在centos7.6中挂载个硬盘,结果刚在虚拟机中添加了一块硬盘,再次打开系统时,居然就 ...
- Linux命令——procinfo
简介 proc文件系统是一个虚拟文件系统,包含有关进程和系统信息的文件. proc 文件系统开机时自动挂载并映射到/proc目录.许多程序从/proc目录中检索信息,对其进行处理并使其易于用于各种目的 ...
- STM32定时器配置(TIM1、TIM2、TIM3、TIM4、TIM5、TIM8)高级定时器+普通定时器,定时计数模式下总结
文章结构: ——> 一.定时器基本介绍 ——> 二.普通定时器详细介绍TIM2-TIM5 ——> 三.定时器代码实例 一.定时器基本介绍 之前有用过野火的学习板上面讲解很详细,所以 ...
- C#ThreadPool类—多线程
标题:ThreadPool Class 地址:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.threadpool?redir ...