实现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 ...
随机推荐
- Android NDK 学习之在C中抛出异常
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...
- List集合和Set集合互转
List集合转成Set集合(如果List集合的元素有重复,转成Set集合就会去掉重复的数据,每条数据只保留一条) //List转化成Set List<String> list = new ...
- redis入门初学知识
一. Redis 介绍 Remote Dictionary Server(Redis)是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提 ...
- SQL SERVER-Login搬迁脚本
USE master GO IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL DROP PROCEDURE sp_hexadecimal GO CREATE PR ...
- JAVA笔记整理(二),下载安装JDK
Windows平台 1.登录Oracle官方网站(http://www.oracle.com/index.html),找到下载 2.选择要下载的版本,点击JDK DOWNLOAD 3.下载文件,先勾选 ...
- Linux下常用mysql命令【2】
1.开启和关闭 1.1.开启 systemctl start mysqld 1.2.关闭 systemctl stop mysqld 1.3.重启 systemctl restart mysqld 回 ...
- java.lang.Override注解
@Override注解的作用 当你想重写父类的某个方法时,它可以帮你检查方法的正确性. 举例说明 比如说我们重写父类的toString()方法,但我们现在将toString这个方法名拼错了,这是它会在 ...
- Go语言中的IO操作、Flag包以及urfave/cli命令行框架
一.格式化输入和输出 1.从终端获取用户的输入 fmt.Scanf 空格作为分隔符,占位符和格式化输出的一致 fmt.Scan 从终端获取用户的输入,存储在Scanln中的参数里,空格和换行符作为 ...
- Scala环境安装步骤
1.scala解释器本地安装 2.IDEA安装 3.安装IDEA的scala插件 4.创建maven项目 5.安装ScalaSDK
- 在angular项目中使用web-component ----How to use Web Components with Angular
原文: https://medium.com/@jorgecasar/how-to-use-web-components-with-angular-41412f0bced8 ------------- ...