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的更多相关文章

  1. Java 多线程(二)之 Thread 优先级

    目录 Thread 中线程优先级相关属性 相关函数 优先级初始化 设置优先级 获取优先级 默认优先级 指定优先级 注意事项 优先级继承 @ Thread 中线程优先级相关属性 每个线程均有优先级,在 ...

  2. java 多线程二

    java 多线程一 java 多线程二 java 多线程三 java 多线程四 线程中断: /** * Created by root on 17-9-30. */ public class Test ...

  3. “全栈2019”Java多线程第十章:Thread.State线程状态详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  4. java多线程机制中的Thread和Runnable()区别

    1.java语言使用Thread类及其子类对象来表示线程,新建的一个线程声明周期中经历 新建.(声明一个线程,此时他已经有了相应的内存空间和其他资源),运行(线程创建之久就据用了运行的条件,一旦轮到使 ...

  5. java多线程(二)之实现Runnable接口

    一.java多线程方式2: 实现Runnable接口 好处:a. 可以避免由于java单继承带来的局限性. b. 适合多个相同的程序的代码去处理同一个资源的情况, 把线程与程序的代码, 数据有效分离, ...

  6. Java多线程(二) 多线程的锁机制

    当两条线程同时访问一个类的时候,可能会带来一些问题.并发线程重入可能会带来内存泄漏.程序不可控等等.不管是线程间的通讯还是线程共享数据都需要使用Java的锁机制控制并发代码产生的问题.本篇总结主要著名 ...

  7. 从零开始学习Java多线程(二)

    前面已经简单介绍进程和线程,为后续学习做铺垫.本文讨论多线程传参,Java多线程异常处理机制. 1. 多线程的参数传递 在传统开发过程中,我们习惯在调用函数时,将所需的参数传入其中,通过函数内部逻辑处 ...

  8. Java多线程(二) —— 深入剖析ThreadLocal

    对Java多线程中的ThreadLocal类还不是很了解,所以在此总结一下. 主要参考了http://www.cnblogs.com/dolphin0520/p/3920407.html 中的文章. ...

  9. java多线程二之线程同步的三种方法

          java多线程的难点是在:处理多个线程同步与并发运行时线程间的通信问题.java在处理线程同步时,常用方法有: 1.synchronized关键字. 2.Lock显示加锁. 3.信号量Se ...

随机推荐

  1. MySQL 性能优化的最佳20多条经验分享(二)(转)

    11. 尽可能的使用 NOT NULL 除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL.这看起来好像有点争议,请往下看. 首先,问问你自己"Empt ...

  2. java使用普通算法实现99乘法表,使用递归实现99乘法表

    public class recursionTest { public static void main(String[] args) { //jiujiu(); m(9); } /* * for循环 ...

  3. Linux下一次删除百万文件

    Linux下一次删除百万文件 线上环境遇到的一个问题,文件数量过多,执行rm命令报错 # rm -f ./* -bash: /bin/rm: Argument list too long 根据报错检查 ...

  4. 我的Android进阶之旅------&gt; Android在TextView中显示图片方法

    面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包括图像的文本信息).并简要说明实现方法. 答案:Android SDK支持例如以下显示富文本信息的方式. 1.使用T ...

  5. HttpClient4.2 Fluent API学习

    相比于HttpClient 之前的版本号,HttpClient 4.2 提供了一组基于流接口(fluent interface)概念的更易使用的API,即Fluent API. 为了方便使用,Flue ...

  6. ZKWeb网页框架2.0正式发布

    2.0.0更新的内容有 更新框架要求 框架要求从 netstandard 1.6 升到 netstandard 2.0 框架要求从 netcoreapp1.1 升到 netcoreapp2.0 更新引 ...

  7. 《About Face 3:交互设计精髓》【PDF】下载

    <About Face 3:交互设计精髓>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230384328 内容简介 全书分成3篇:第1 ...

  8. 英式英语VS美式英语

  9. dubbo+zookeeper+jsp+springmvc+spring+mybatis+mysql+maven完整示例

    项目分为三部分,这里分为三个maven项目(基于web,所以最后一个为maven创建的web项目) 1.接口定义以及实体类定义(api+pojo) --- maven创建java项目,打包成jar 2 ...

  10. 【python】内部函数