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

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. linux修改源镜像地址

    1.1 CentOS修改yum源镜像地址为:mirrors.163.com (也可以改为阿里云镜像) 1.首先备份系统自带yum源配置文件/etc/yum.repos.d/CentOS-Base.re ...

  2. 华为oj-判断输入的字符串是不是一个有效的IP地址

    题目标题: 判断输入的字符串是不是一个有效的IP地址 详细描述: 请实现如下接口 boolisIPAddressValid(constchar* pszIPAddr) 输入:pszIPAddr 字符串 ...

  3. 微信小程序学习笔记四 页面的生命周期

    1. 生命周期 1.1 对应阶段说明 onLOad(Object query) 1.1 页面加载时触发, 一个页面只会调用一次, 可以在 onLoad的参数中获取打开当前页面路径中的参数 1.2 参数 ...

  4. Flink 运行时架构

    参考链接:https://blog.csdn.net/dajiangtai007/article/details/88575553 1.Flink 运行时架构 Flink 运行时架构主要包含几个部分: ...

  5. linux备份恢复命令

    dump 发行版不自带,需要 yum 或 apt 安装.安装时 restore 也会自动安装. 支持分区和增量备份(仅支持分区增量,目录备份不支持增量).(第一次完全备份,第二次及以后只备份增加和修改 ...

  6. unity优化 — UGUI纹理格式的选择

    首次界面打开加载的资源(如 贴图)会被缓存在内存中,再次打开界面由于内存中已有了资源 所以会更快.如何让首次打开界面会更快呢? 图片是否进行了有效的压缩.Android 平台下不带透明通道 优先使用E ...

  7. jwt三种方式

    package library.book.demo.config.loginconfig; import com.alibaba.fastjson.JSON; import com.sun.org.a ...

  8. Ubuntu 16.04LTS安装flashplayer

    转载自http://www.linuxdiyf.com/linux/20084.html 在安装Ubuntu 16.04LTS后,播放有视频的网页时,总提示你要安装缺失的插件,在 ubuntu 系统下 ...

  9. 阿里云服务器上部署java项目(安装jdk,tomcat)

    安装JDK a.执行下面的yum指令安装,无线配置环境变量. 1.yum -y update #首先更新一下YUM源2.yum list Java* ---------#列出所有的JDK 3.yum ...

  10. Hive的分桶表

    [分桶概述] Hive表分区的实质是分目录(将超大表的数据按指定标准细分到指定目录),且分区的字段不属于Hive表中存在的字段:分桶的实质是分文件(将超大文件的数据按指定标准细分到分桶文件),且分桶的 ...