博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程 start 和 run 方法到底有什么区别?
阅读量:6509 次
发布时间:2019-06-24

本文共 1990 字,大约阅读时间需要 6 分钟。

昨天栈长介绍了《》线程分组的妙用。今天,栈长会详细介绍 Java 中的多线程 start() 和 run() 两个方法,Java 老司机请跳过,新手或者对这两个不是很理解的可以继续往下看。

首先要知道实现多线程最基本的两种方式:

1、继承 java.lang.Thread 类;

2、实现 java.lang.Runnable接口;

其中 Thread 类也是实现了 Runnable 接口,而 Runnable 接口定义了唯一的一个 run() 方法,所以基于 Thread 和 Runnable 创建多线程都需要实现 run() 方法,是多线程真正运行的主方法。

@FunctionalInterfacepublic interface Runnable {    public abstract void run();}

而 start() 方法则是 Thread 类的方法,用来异步启动一个线程,然后主线程立刻返回。该启动的线程不会马上运行,会放到等待队列中等待 CPU 调度,只有线程真正被 CPU 调度时才会调用 run() 方法执行。

所以 start() 方法只是标识线程为就绪状态的一个附加方法,以下 start() 方法的源码,其中 start0() 是一个本地 native 方法。

public synchronized void start() {    if (threadStatus != 0)        throw new IllegalThreadStateException();    group.add(this);    boolean started = false;    try {        start0();        started = true;    } finally {        try {            if (!started) {                group.threadStartFailed(this);            }        } catch (Throwable ignore) {            /* do nothing. If start0 threw a Throwable then              it will be passed up the call stack */        }    }}

请注意,start() 方法被标识为 synchronized 的,即为了防止被多次启动的一个同步操作。

那么你会问了,为什么要有两个方法,直接用一个 run() 方法不就行了吗!? 还真不行,如果直接调用 run() 方法,那就等于调用了一个普通的同步方法,达不到多线程运行的异步执行,来看下面的例子。

/** * 微信公众号:Java技术栈 */public static void main(String[] args) {    Thread thread = new Thread(() -> {        try {            Thread.sleep(3000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("Java技术栈");    });    long start = System.currentTimeMillis();    thread.start();    System.out.println(System.currentTimeMillis() - start);    start = System.currentTimeMillis();    thread.run();    System.out.println(System.currentTimeMillis() - start);}

程序输出:

0Java技术栈3000Java技术栈

从程序输出结果可以看出,启动 start 方法前后只用了 0 毫秒,而启动 run 方法则阻塞了 3000 毫秒等程序执行完再继续执行,这就是同步与异步的一个最重要的区别。

看完这篇,你应该对 start 和 run 方法有了一个大概的掌握吧,再也不怕面试官问你这两个的区别了吧!

动手转发给更多的朋友吧!


更多 Java 多线程技术文章请在Java技术栈微信公众号后台回复关键字:多线程。

本文原创首发于微信公众号:Java技术栈(id:javastack),关注公众号在后台回复 "多线程" 可获取更多,转载请原样保留本信息。
你可能感兴趣的文章
iis里运行php_让IIS也能运行PHP网页
查看>>
php tp6 错误接管分析,TP6实现原理分析系列(二):请求与响应
查看>>
php 继承类构造函数,PHP面向对象之继承构造函数
查看>>
php5.4 升级,php-5.4 升级到 php7.2
查看>>
php js json 转换包,json转换js ,php重组数组
查看>>
linux php 相关配置,linux下安装apache与php及其相关配置攻略
查看>>
matlab线性规划上限,matlab解决非线性规划,其中限制条件是集合如x属于{0,1},这样肿么编程?...
查看>>
mysql 更新memcache,MySQL触发器自动更新memcache
查看>>
怎样让php支持中文文件名,让phpmailer支持中文名称的附件
查看>>
matlab如何表示结构体,matlab中怎么定义结构体啊 !!!
查看>>
matlab第二章习题答案,matlab第二章习题答案
查看>>
java hibernate注解详解,Hibernate注解使用以及Spring整合
查看>>
lnmp php t扩展,Linux + Lnmp php编译安装fileinfo扩展 苹果CMS
查看>>
oracle字符串中字符个数字类型,Oracle实现获得字符串中指定字符个数的方法
查看>>
oracle sql中 v¥,sql – Oracle中匿名TABLE/VARRAY类型示例详解
查看>>
be更改密码Oracle报错,转:oracle用户密码密码复杂度设置
查看>>
php parse url ctf,一道CTF题目的探究
查看>>
linux进程inject,linux-inject:注入代码到运行的Linux进程中
查看>>
linux 安装perl 模块权限,Linux系统非root用户安装perl模块(转)
查看>>
嵌入式linux编译程序,构造嵌入式Linux(一):Kernel编译
查看>>