资讯专栏INFORMATION COLUMN

多线程 start 和 run 方法到底有什么区别?

SoapEye / 236人阅读

摘要:昨天栈长介绍了多线程可以分组,还能这样玩线程分组的妙用。今天,栈长会详细介绍中的多线程和两个方法,老司机请跳过,新手或者对这两个不是很理解的可以继续往下看。

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

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

1、继承 java.lang.Thread 类;

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

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

@FunctionalInterface
public 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);
}

程序输出:

0
Java技术栈
3000
Java技术栈

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

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

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

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

本文原创首发于微信公众号:Java技术栈(id:javastack),关注公众号在后台回复 "多线程" 可获取更多,转载请原样保留本信息。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72147.html

相关文章

  • 你真应该再了解些Handler机制

    摘要:当睡眠时间为时,检测线程是否中断,并清除线程的中断状态标记。当前线程可能再次获得执行,也可能没获得。直到该对象调用了或者后,该线程才能重新获得,或者有可能获得对象的锁,然后继续执行后面的语句。 showImg(https://segmentfault.com/img/remote/1460000017806837); 背景介绍 我们在Android开发过程中,几乎都离不开线程。但是你对...

    李世赞 评论0 收藏0
  • 【面试】Java相关

    摘要:可能会持有相同的值对象但键对象必须是唯一的。当有新任务到达时,线程池没有线程则创建线程处理,处理完成后该线程缓存秒,过期后回收,线程过期前有新任务到达时,则使用缓存的线程来处理。解决死锁问题的三种方法预防死锁检测死锁及避免死锁。 最近辞职准备面试,顺便整理一下面试题分享给大家,如有错误欢迎指出 01. 你对面向对象思想的理解? 面向对象编程简称OOP,是开发程序的一种方法、思想。面向...

    icattlecoder 评论0 收藏0
  • Java面试题

    摘要:近段时间在准备实习的面试,在网上看到一份面试题,就慢慢试着做,争取每天积累一点点。现在每天给自己在面试题编写的任务是题,有时候忙起来可能就没有时间写了,但是争取日更,即使当天没更也会在之后的更新补上。     近段时间在准备实习的面试,在网上看到一份面试题,就慢慢试着做,争取每天积累一点点。    暂时手头上的面试题只有一份,题量还是挺大的,有208题,所以可能讲的不是很详细,只是我自...

    OnlyMyRailgun 评论0 收藏0
  • Thread、HandlerHandlerThread关系何在?

    摘要:总结的使用方法还是比较简单的,但是我们要明白一点的是如果一个线程要处理消息,那么它必须拥有自己的,并不是在哪里创建,就可以在哪里处理消息的。如果不用的话,需要手动去调用和这些方法。 前言 前几天看到一道面试题:Thread、Handler和HandlerThread有什么区别?,这个题目有点意思,对于很多人来说,可能对Thread和Handler很熟悉,主要涉及到Android的消息机...

    hankkin 评论0 收藏0
  • Java线程池架构(一)原理源码解析

    摘要:在前面介绍的文章中,提到了关于线程池的创建介绍,在文章之系列外部中第一部分有详细的说明,请参阅文章中其实说明了外部的使用方式,但是没有说内部是如何实现的,为了加深对实现的理解,在使用中可以放心,我们这里将做源码解析以及反馈到原理上,工具可 在前面介绍JUC的文章中,提到了关于线程池Execotors的创建介绍,在文章:《java之JUC系列-外部Tools》中第一部分有详细的说明,请参...

    wthee 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<