java多线程(二)-Runnable和Thread
Java在顺序性语言的基础上提供了多线程的支持。Java的线程机制是抢占式的。这表示调度机制会周期的中断线程,将上下文切换到另一个线程,从而为每个线程都提供时间片。(与抢占式多线程对应的是 协作式多线程,每个子线程都自动的放弃控制,这就要求程序员需要在子线程的代码中插入某些让步语句)。
Java的多线程,最常见的是 Runnable和Thread类。
示例代码:src/thread_runnable/CountDown.java
public class CountDown implements Runnable{
protected int countDown = 5;
private static int myId= 0;
private final int taskId = myId++;
public CountDown() {
super();
}
public CountDown(int countDown) {
super();
this.countDown = countDown;
}
public String status() {
return "#" + taskId + "#(" + (countDown>0 ? countDown : "Over") + "), " + Thread.currentThread().getName();
}
public void run() {
while(countDown-- > 0){
System.out.println(status());
Thread.yield();
}
}
输出结果:

通过输出可以看出来,Runnable的运行其实还是main线程。(当一个java程序运行时,默认会启动两个线程,一个main线程,一个gc线程)。
所以说,Runnable接口其实就是 描述任务的接口,要想定义某个任务,可以 实现Runnable接口并编写run()方法。
另外,代码当中的 Thread.yield() 方法是对线程调度器的一种建议。意思是“当前线程最重要的部分已经执行完毕了,可以把时间片切换给其他线程了”。当然,该方法也就是个建议而已,实际效果这个取决于具体的jvm。就像你跟领导提意见一样,建议可以提,但是领导是否采纳那就另一说了。因为java的线程机制是抢占式机制。
而实际上,真正实现启动新线程的是 Thread类,
示例代码:src/thread_runnable/DirectThread.java
public class DirectThread extends Thread{
protected int countDown = 5;
public String status() {
return "###(" + (countDown>0 ? countDown : "Over") + "), " + Thread.currentThread().getName();
}
@Override
public void run() {
// TODO Auto-generated method stub
while(countDown-- > 0){
System.out.println(status());
}
}
public static void main(String[] args) {
System.out.println("DirectThread --- main start, " + Thread.currentThread().getName());
new DirectThread().start();
System.out.println("DirectThread --- main end, " + Thread.currentThread().getName());
}
}
输出结果:

通过代码和输出结果,我们可以观察到Thread类,的确启动了一个新线程,并且可以看到main函数方法最后一条语句执行完,才开始输出Thread类中 run()方法当中的内容。这个run()方法就是新线程需要执行的任务。
不过在实际当中,我们经常并不是单独使用Thread类,而是在Thread类的构造器中传递类一个 Runnable()对象。然后调用Thread对象的start()方法来为该线程执行必须的初始化操作。然后系统会自动调用Runnable的run()方法。
示例代码:src/thread_runnable/ThreadRunnable.java
public class ThreadRunnable{
private static final String TAG = "LiftOff";
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("main start, " + Thread.currentThread().getName());
for (int i=0; i<3; i++){
Thread thread = new Thread(new CountDown());
thread.start();
}
System.out.println("main end, " + Thread.currentThread().getName());
}
}
输出结果: (每次执行的结果都有差别)

可以看出,新启动了三个新线程,来输出各自的任务,并且从结果,还可以看出,三个线程的执行顺序都是随机的,并且每次执行的结果都不同。那么这就说明线程运行的时候是被混在一起的,这种线程的切换就是线程调度器来进行自动控制的。具有不确定性。而对于多核处理器,也有可能在几个不同的核上同时执行着几个线程,但是对于输出信息到控制台,(就是 System.out.println()语句),这种输出资源是只存在一份的。
既然可以直接使用Thread()对象的start()方法来启动新线程,那为什么还要使用Runnable()对象来传递到Thread()对象的构造方法中,在Runnable对象的run()方法中来执行任务呢。原因如下:
(1) java是单根继承,而Runnable是interface。方便了任务的继承。
(2) 解耦,任务本身与线程分离,两者相互独立。也方便任务代码被多个线程共享。
这几篇java多线程文章的demo代码下载地址 http://download.csdn.net/detail/yaowen369/9786452
-------
作者: www.yaoxiaowen.com
github: https://github.com/yaowen369
java多线程(二)-Runnable和Thread的更多相关文章
- Java 多线程(二)之 Thread 优先级
目录 Thread 中线程优先级相关属性 相关函数 优先级初始化 设置优先级 获取优先级 默认优先级 指定优先级 注意事项 优先级继承 @ Thread 中线程优先级相关属性 每个线程均有优先级,在 ...
- java 多线程二
java 多线程一 java 多线程二 java 多线程三 java 多线程四 线程中断: /** * Created by root on 17-9-30. */ public class Test ...
- “全栈2019”Java多线程第十章:Thread.State线程状态详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- java多线程机制中的Thread和Runnable()区别
1.java语言使用Thread类及其子类对象来表示线程,新建的一个线程声明周期中经历 新建.(声明一个线程,此时他已经有了相应的内存空间和其他资源),运行(线程创建之久就据用了运行的条件,一旦轮到使 ...
- java多线程(二)之实现Runnable接口
一.java多线程方式2: 实现Runnable接口 好处:a. 可以避免由于java单继承带来的局限性. b. 适合多个相同的程序的代码去处理同一个资源的情况, 把线程与程序的代码, 数据有效分离, ...
- Java多线程(二) 多线程的锁机制
当两条线程同时访问一个类的时候,可能会带来一些问题.并发线程重入可能会带来内存泄漏.程序不可控等等.不管是线程间的通讯还是线程共享数据都需要使用Java的锁机制控制并发代码产生的问题.本篇总结主要著名 ...
- 从零开始学习Java多线程(二)
前面已经简单介绍进程和线程,为后续学习做铺垫.本文讨论多线程传参,Java多线程异常处理机制. 1. 多线程的参数传递 在传统开发过程中,我们习惯在调用函数时,将所需的参数传入其中,通过函数内部逻辑处 ...
- Java多线程(二) —— 深入剖析ThreadLocal
对Java多线程中的ThreadLocal类还不是很了解,所以在此总结一下. 主要参考了http://www.cnblogs.com/dolphin0520/p/3920407.html 中的文章. ...
- java多线程二之线程同步的三种方法
java多线程的难点是在:处理多个线程同步与并发运行时线程间的通信问题.java在处理线程同步时,常用方法有: 1.synchronized关键字. 2.Lock显示加锁. 3.信号量Se ...
随机推荐
- 深入理解php内核 编写扩展_III- 资源
原文:http://devzone.zend.com/article/1024-Extension-Writing-Part-III-Resources 编写扩展_III- 资源 介绍 资源 初始化资 ...
- 矩阵的奇异值分解(SVD)(理论)
矩阵的奇异值分解(Singular Value Decomposition,SVD)是数值计算中的精彩之处,在其它数学领域和机器学习领域得到了广泛的应用,如矩阵的广义逆,主分成分析(PCA),自然语言 ...
- 开源纯C#工控网关+组态软件(七)数据采集与归档
一. 引子 在当前自动化.信息化.智能化的时代背景下,数据的作用日渐凸显.而工业发展到如今,科技含量和自动化水平均显著提高,但对数据的采集.利用才开始起步. 对工业企业而言,数据采集日益受到重视, ...
- jQuery的$.ajax方法响应数据类型有哪几种?本质上原生ajax响应数据格式有哪几种,分别对应哪个属性?
jQuery的$.ajax方法响应数据类型有:xml.html.script.json.jsonp.text 本质上原生ajax响应数据格式只有2种:xml和text,分别对应xhr.response ...
- 开源API测试工具 Hitchhiker v0.6更新 - 改进压力测试
Hitchhiker 是一款开源的支持多人协作的 Restful Api 测试工具,支持Schedule, 数据对比,压力测试,支持上传脚本定制请求,可以轻松部署到本地,和你的team成员一起协作测试 ...
- vue init失败解决方案-终极版
//由于windows系统的某方面问题,vue脚手架安装可能会出现第一证书丢失 // 报错:vue-cli · Failed to download repo vuejs-templates/webp ...
- java微信开发API解析(二)-获取消息和回复消息
java微信开发API解析(二)-获取消息和回复消息 说明 * 本演示样例依据微信开发文档:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/20 ...
- myeclipse tomcat java.lang.OutOfMemoryError: PermGen space错误的解决方法
错误代码: java.lang.OutOfMemoryError: PermGen space 原因分析: myeclipse或tomcat的内容分配的不够用,启动失败 解决方法: 1.找到tomca ...
- Objective-C基础语法高速入门
Objective-C是Mac软件开发领域最基本的开发语言,假如我们对C语言已经非常熟悉或者具有面向对象语言的基础.对于我们学习Objective-C将会非常实用. 方法调用(Calling Meth ...
- 1692: [Usaco2007 Dec]队列变换|后缀数组|贪心
将字符串翻转后接到原串的后面,中间加一个分隔符,每次都贪心选择rankrank小的那个 事实上就是练习一发后缀数组的模板 #include<algorithm> #include<i ...