一、任务和线程

  《thinking in java》中专门有一小节中对线程和任务两个概念进行了具体的区分,这也恰好说明任务和线程是有区别的。

  正如前文所提到的,任务只是一段代码,一段要达成你目的的代码,这段代码写在哪,怎么写其实无所谓,只是因为你希望java的多线程机制能够识别并调用你编写的任务,所以规定了Runnable接口,让你的任务来实现该接口,把你想做的工作在实现该接口的run方法中实现。

  那么,已经定义了任务类,那任务和线程有什么关系呢?

  java的线程是用来驱动任务执行的,也就是说你得把任务挂载到一个线程上,这样该线程才能驱动你定义的任务来执行。

二、定义线程

  1.显示的定义线程的过程就是将任务附着到线程的过程。线程Thread自身并不执行任何操作,它只是用来被多线程机制调用,并驱动赋予它的任务。

  如前次文章提到的任务类定义如下:

public class Task implements Runnable {
protected int countDown = 10;
private static int taskCount = 0 ;
private final int id = taskCount++;
public Task(){}
public Task(int countDown){
this.countDown = countDown;
}
public String status(){
return "#"+id+"("+(countDown>0?countDown:"Task!")+"). ";
}
@Override
public void run() {
while(countDown-->0){
System.out.print(status());
Thread.yield();
}
}
}

  声明线程并将任务附着到该线程上:

Thread t = new Thread(new Task());

  这样,任务就附着给了线程,下面就是让线程启动,只需要如下的调用:

t.start();

  至此,线程声明ok。

  有时,我会想,是不是像任务和线程的概念分离一样,此时只是声明了线程,而java的线程机制并不会调用该线程运行,还需要特殊的调用才能实现多线程执行。但是下面的一段代码告诉我,Thread类的start方法就是触发了java的多线程机制,使得java的多线程能够调用该线程

public static void main(String[] args){
Thread t = new Thread(new Task());
t.start();
System.out.println("Waiting for Task");
}

输出结果如下:

Waiting for Task
#0(9). #0(8). #0(7). #0(6). #0(5). #0(4). #0(3). #0(2). #0(1). #0(Task!).

  先输出“Waiting for Task”证明调用完start()方法后,立即返回了主程序,并开始执行下面的语句。而你声明的t线程已经去被java的多线程机制调用,并驱动着它的任务运行了。

  2.补充

  想看到更多的线程任务运行,可以用下面的这段代码

public static void main(String[] args){
for(int i = 0 ; i < 5 ; i++){
new Thread(new Task()).start();
}
System.out.println("Waiting for Task");
}

  输出如下:

Waiting for Task
#0(9). #2(9). #4(9). #0(8). #2(8). #4(8). #0(7). #2(7). #4(7). #0(6). #2(6). #4(6). #0(5). #2(5). #4(5). #0(4). #2(4). #4(4). #3(9). #2(3). #4(3). #2(2). #4(2). #2(1). #4(1). #2(Task!). #4(Task!). #1(9). #0(3). #0(2). #0(1). #0(Task!). #3(8). #1(8). #3(7). #1(7). #3(6). #1(6). #3(5). #3(4). #3(3). #3(2). #3(1). #3(Task!). #1(5). #1(4). #1(3). #1(2). #1(1). #1(Task!).

  上面的输出说明不同任务的执行在线程被换进换出时混在了一起——由线程调度器自动控制。不同版本的jdk线程调度方式不同,所以产生的结果也不相同。

  这里涉及了垃圾回收器的一个问题,每个Thread都注册了它自己,因此确实有一个对它的引用,而且在它的任务退出其run并死亡之前,垃圾回收器无法清除它。

注:以上代码均来自《thinking in java》,内容大部分是个人理解和总结,如有错误请各位指正

Java多线程——<二>将任务交给线程,线程声明及启动的更多相关文章

  1. Java多线程(三)如何创建线程

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

  2. Java多线程(一) 什么是线程

    声明:本系列大多是翻译自https://www.javatpoint.com,加上自己的增删改,尽力写的系统而通俗易懂,后文不再重复声明. 点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更 ...

  3. “全栈2019”Java多线程第十四章:线程与堆栈详解

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

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

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

  5. “全栈2019”Java多线程第七章:等待线程死亡join()方法详解

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

  6. “全栈2019”Java多线程第六章:中断线程interrupt()方法详解

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

  7. Java多线程系列--“基础篇”06之 线程让步

    概要 本章,会对Thread中的线程让步方法yield()进行介绍.涉及到的内容包括:1. yield()介绍2. yield()示例3. yield() 与 wait()的比较 转载请注明出处:ht ...

  8. Java多线程系列--“基础篇”07之 线程休眠

    概要 本章,会对Thread中sleep()方法进行介绍.涉及到的内容包括:1. sleep()介绍2. sleep()示例3. sleep() 与 wait()的比较 转载请注明出处:http:// ...

  9. Java多线程系列--“基础篇”10之 线程优先级和守护线程

    概要 本章,会对守护线程和线程优先级进行介绍.涉及到的内容包括:1. 线程优先级的介绍2. 线程优先级的示例3. 守护线程的示例 转载请注明出处:http://www.cnblogs.com/skyw ...

随机推荐

  1. mysql一对多关联查询的时候筛选条件

    mysql实现users 表和 logoin_log表是一对多, 现在是把user的信息找出来 关联上一些 logoin_log表的数据, 因为a表是多的一方,要多他的数据进行一些条件匹配,这个sql ...

  2. 苹果在Xcode6中弃用segue的push和model

    苹果在Xcode6中弃用了segue的push和model.被show和present取代. 下面是新版本中每种类型的使用总结和例子.建议自己使用前先在测试项目中自己试一试 Show 根据当前屏幕中的 ...

  3. GPRS组网的几种方案【来自网络】

    GPRS组网的几种方案:1) 方案一:中心采用ADSL等INTELNET公网连接,采用公网固定IP或者公网动态IP+DNS解析服务.此种方案向先INTERNET运营商申请ADSL等宽带业务.     ...

  4. JAVA:类,对象,成员属性,成员方法,构造方法,类变量,类方法<2>

    一.类的定义 一个全面的类定义是比较复杂的,  定义如下:

  5. ajax学习计划

    来自http://segmentfault.com/a/1190000004322487?utm_source=Weibo&utm_medium=shareLink&utm_campa ...

  6. java非静态变量初始化

    java费静态变量的初始化分为两种情况,一种是局部变量,一种是类的域. 对于类的域,java在类初始化时,会为变量赋一个初始值.对于基本数据类型,java会将初始值设置为二进制0,具体为将boolea ...

  7. ZigBee安全相关

    ZigBee安全由AES加密算法和CCM操作方式作为安全方案,广泛使用在ZigBee联盟的通信协议中.ZDO层负责安全策略和安全配置的管理. Technorati 标签: ZigBee 安全 2. 配 ...

  8. ubuntu 常用参数设置

        在Linux下,对于参数的设置,一般来说,都遵循这个规律.每一个功能程序,一定对于一个对于名字的配置文件.     涉及到多用户的功能配置,一定有一个全局的配置文件,对所有用户都生效,而每个用 ...

  9. 隐马尔科夫模型及Viterbi算法的应用

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4335810.html 一个例子: 韦小宝使用骰子进行游戏,他有两种骰子一种正常的骰子,还有一 ...

  10. DevExpress学习笔记1-ProductsDemo.Win

    最近在学习ProductsDemo.Win,有一些体会记录下来,大家分享: 在Contacts模块: 在Private Sub UpdateCurrentContact()过程添加一句:InitInd ...