简单理解启动线程的几种方式:

1. 实现Runnable接口创建一个任务, 调用myTask.run()方法来启动它

2, 构建Thread对象, 调用thread.start()方法启动

这里可以看到, 我们给Thread构造器传入了runable对象

细心的小伙伴看到这里可能会有疑惑, 我们知道Thread同样有run方法, 这里为什么要调用thread.start()而不是thread.run()呢 ?

这里的target就是我们传进去的runable对象,所以thread的run方法里也是执行了runable的run方法

再看下start方法, 我这里看到的是android-30的源码,可以看到Android在这里做了一些修改

注释里这段英文的意思是说:

调用该方法来启动一个线程时, java VM会去call run方法

调用该方法后会有两个线程同时运行(主线程执行完 start()后返回,调用run方法后子线程也开始执行)

多次启动一个线程是非法的

特别是, 如果一个线程被执行完成, 它将不能再被启动

所以, 回答上面那个问题, 为什么调用start来启动线程而不是直接调用run呢?

因为start方法中 1), 会判断当前线程的状态,如果已经被启动, 则会抛出 IllegalThreadStateException

2), 会将该线程加到 一个group里, 这个group可能包含了当前线程的多个实例。加到这里有什么好处呢?。。。。,,等我知道了再来写

3, 通过Executor来管理线程

CachedThreadPool

FixedThreadPool创建固定数量的线程池

SingleThreadExecutor

这里我们创建了3个线程(id分别为0,1,2),并使用singleThreadExecutor来启动它, 看下运行结果

我们看到: 1), 线程是严格按照我们期望的顺序去启动的(0--> 1 --> 2)。 我们知道在多线程中, 线程间的调度是由线程调度器来完成的, 调度过程可以说是不确定的, 但是SingleThreadExecutor会按照线程被提交的顺序去执行。所以我们说SingleThreadExecutor会序列化所有提交给它的任务,并且维护它自己的悬挂任务队列。

2), 第一个线程执行完成之后才去执行下一个

因此,如果我们有几个线程需要访问同一个系统资源时, 使用这种方式可以确保在任何时刻都只有唯一的线程在操作数据, 从而实现同步,而且线程执行的顺序还是可控的。

4, 通过Callable接口创建线程

在上文中, 我们尝试了通过实现Runnable接口来创建线程。 但是它并不会返回任何值。

那么如果我们希望在任务完成时有返回值, 就可以实现Callable接口。 实现callable接口需要重写call方法, call方法的返回值就是该任务的返回

需要特别注意的是, 我们必须使用ExecutorService.submit()方法来启动它

看下运行结果:

5, 继承Thread类创建线程

小结--创建/启动线程的方式:

1)让我们的task实现runnable接口, 重写run方法, 使用mytask.run()启动

2)让我们的task实现runnable接口,重写run方法, 使用ExecutorService.execute(runnable)方式启动。 常用的ExecutorService有 CachedThreadPool, FixedThreadPool 和 SingleThreadExecutor

3)在Thread的构造方法中传入runnable对象, 使用thread.start()方式启动 (start方法本质上还是去调用了run方法, 但是在调用之前多了一些检查的工作)

4)让我们的task继承自Thread, 重写run()方法, 使用thread.start()方式启动

5)让我们的task实现Callable接口, 使用ExecutorService.submit()方式启动。 该方法可以在任务执行完后给我们返回值

其中1,2,3可以归为同类, 因为都是实现了runnable接口

java多线程--启动线程的更多相关文章

  1. java——多线程—启动线程

    继承Thread启动线程 package com.mycom.继承Thread启动线程; /** * * 继承Thread类启动线程的步骤 * 1.定义自定义线程类并继承Thread * 2.重写ru ...

  2. Java多线程之线程的启动

    Java多线程之线程的启动 一.前言 启动线程的方法有如下两种. 利用Thread 类的子类的实例启动线程 利用Runnable 接口的实现类的实例启动线程 最后再介绍下java.util.concu ...

  3. Java多线程之线程其他类

    Java多线程之线程其他类 实际编码中除了前面讲到的常用的类之外,还有几个其他类也有可能用得到,这里来统一整理一下: 1,Callable接口和Future接口 JDK1.5以后提供了上面这2个接口, ...

  4. Java多线程之线程的同步

    Java多线程之线程的同步 实际开发中我们也经常提到说线程安全问题,那么什么是线程安全问题呢? 线程不安全就是说在多线程编程中出现了错误情况,由于系统的线程调度具有一定的随机性,当使用多个线程来访问同 ...

  5. Java多线程之线程的控制

    Java多线程之线程的控制 线程中的7 种非常重要的状态:  初始New.可运行Runnable.运行Running.阻塞Blocked.锁池lock_pool.等待队列wait_pool.结束Dea ...

  6. Java多线程02(线程安全、线程同步、等待唤醒机制)

    Java多线程2(线程安全.线程同步.等待唤醒机制.单例设计模式) 1.线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量 ...

  7. java多线程与线程间通信

    转自(http://blog.csdn.net/jerrying0203/article/details/45563947) 本文学习并总结java多线程与线程间通信的原理和方法,内容涉及java线程 ...

  8. Java多线程之线程的生命周期

    Java多线程之线程的生命周期 一.前言 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态.在线程的生命周期中,它要经过新建(New).就绪(Runnable).运行(R ...

  9. Java多线程| 01 | 线程概述

    Java多线程| 01 | 线程概述 线程相关概念 进程与线程 进程:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是操作系统进行资源分配与调度的基本单位.可以把进程简单的理解 ...

随机推荐

  1. EL表达式学习(二)

    1.从特定域中获取值: 2.从请求页面的input标签中,获取值:(同servlet中的getParameter和getParameterValues): 3.获取请求头(同servlet中的getH ...

  2. Learning ROS: Managing System dependencies

    Download and install the system dependencies for turtlesim: roscd turtlesim cat package.xml rosdep i ...

  3. maven下载出错

    求解

  4. vue ele 日期时间格式限制不能早于当天,时间转换成时间戳 进行比较

    <el-date-picker             value-format="yyyy-MM-dd HH:mm:ss"             v-model=&quo ...

  5. 浅析mybatis中${}和#{}取值区别

    mybatis作为一个轻量级的ORM框架,应用广泛,其上手使用也比较简单:一个成熟的框架,必然有精巧的设计,值得学习. 在使用mybatis框架时,在sql语句中获取传入的参数有如下两种方式: ${p ...

  6. L2TP协议简介

    传送门:L2TP代码实现 1. L2TP 概述 L2TP(Layer 2 Tunneling Protocol,二层隧道协议)是 VPDN(Virtual Private Dial-up Networ ...

  7. ysoserial CommonsColletions7分析

    CC7也是一条比较通用的链了,不过对于其原理的话,其实还是挺复杂的.文章如有错误,敬请大佬们斧正 CC7利用的是hashtable#readObject作为反序列化入口.AbstractMap的equ ...

  8. 使用 mysql 的 Docker 镜像

    使用 mysql 的 Docker 镜像 前言 之前搞了很多都是手工在操作系统的镜像中安装使用 mysql,作为自己折腾也就算了,作为实际使用实为不妥:Docker最重要的特性就是可扩展性,把各种程序 ...

  9. SpringAOP-动态代理,日志注入

    SpringAOP 前言: 1.AOP定义? 用来干啥的? 怎么用?(怎么跑通它的思路) 代理模式 为啥要学代理模式? -- 因为是SpringAop的底层 原有的代码不敢动,一动就是Bug,.所以使 ...

  10. TP6出现错误 No input file specified.

    解决办法是打开public下的.htaccess文件, 把:RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] 改为:RewriteRule ^(.*)$ index ...