java中thread线程start和run的区别

Java中,线程是程序的执行流,它是在进程中执行的。可以通过继承Thread类或实现Runnable接口来创建线程。在创建线程时,我们需要注意线程的生命周期。在Java中,线程的生命周期可以分为New、Runnable、Blocked、Waiting、Timed Waiting和Terminated这6种状态。

线程的启动是通过调用start方法来实现的;线程的执行是通过run方法来实现的。那么,start和run方法有什么区别呢?

区别1:start方法和run方法的功能不同

start方法的作用是启动一个新线程,新线程会执行对应Thread对象的run方法,当调用start方法后,该线程会被加入到线程调度器的等待队列中,等待获取CPU时间片,从而运行线程。

run方法的作用是实现线程的执行体,也就是线程要执行的任务或操作。如果直接调用run方法,那么相当于在当前的主线程中执行该方法,不会创建新的线程。

下面是两个示例说明:

// 示例1:使用start方法
public class MyThread extends Thread {

    @Override
    public void run() {
        // 实现线程的执行体
        for (int i = 1; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
    }

    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        thread1.start();
        thread2.start();
    }
}

// 示例2:直接调用run方法
public class MyThread implements Runnable {

    @Override
    public void run() {
        // 实现线程的执行体
        for (int i = 1; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
    }

    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        thread1.run();  // 直接调用run方法,相当于在主线程中执行
        thread2.run();
    }
}

在示例1中,通过使用start方法来启动两个线程,新线程会执行MyThread对象的run方法,输出结果如下:

Thread-0:1
Thread-1:1
Thread-0:2
Thread-1:2
Thread-0:3
Thread-1:3
Thread-0:4
Thread-1:4
Thread-0:5
Thread-1:5

在示例2中,直接调用run方法,相当于在主线程中执行,输出结果如下:

main:1
main:2
main:3
main:4
main:5
main:1
main:2
main:3
main:4
main:5

可以看到,直接调用run方法并没有创建新的线程,而是在主线程中执行了MyThread对象的run方法,因此两个线程的执行结果都是在主线程中输出,没有体现出多线程的优势。

区别2:start方法和run方法执行的时间点

start方法调用后会将线程加入到等待队列中,等待获取CPU时间片运行;而run方法直接在当前线程中执行,不会新建线程。

当调用start方法时,线程被加入到等待队列中,等待获取CPU时间片,同时当前线程继续执行下面的代码。当线程获取到时间片后,才会执行线程的run方法,完成对应的任务。

下面是一个示例:

public class MyThread extends Thread {

    @Override
    public void run() {
        try {
            Thread.sleep(5000);  // 线程睡眠5s
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "执行完成");
    }

    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        thread1.start();
        System.out.println(Thread.currentThread().getName() + "继续执行");
    }
}

在上面的示例中,线程1被启动后,会睡眠5s,然后输出一个执行信息。在启动线程1后,主线程继续执行,输出另一个执行信息。输出结果如下:

main继续执行
Thread-0执行完成

可以看到,当主线程输出“继续执行”时,线程1并没有立即执行对应的任务,而是被加入到了等待队列中,等待获取CPU时间片才开始执行任务。5s后,线程1才输出执行完成的信息。

综上所述,start方法和run方法的区别在于:

  • start方法是启动一个新线程,run方法是实现线程的执行体;
  • start方法会将线程加入到等待队列中,等待获取CPU时间片运行,而run方法直接在当前线程中执行;
  • 调用start方法启动线程时,当前线程继续执行下面的代码;线程获取时间片后执行run方法。
阅读剩余 62%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java中thread线程start和run的区别 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • SpringBoot应用启动内置Tomcat的过程源码分析

    下面我将为您详细讲解“SpringBoot应用启动内置Tomcat的过程源码分析”。 SpringBoot应用启动流程 SpringBoot能够提供如此简单易用的开发体验,离不开对应用启动过程的封装和自动配置。下面是SpringBoot应用启动的大体流程: SpringBoot启动类加载:在启动类的main方法中触发SpringApplication.run…

    Java 2023年5月19日
    00
  • Java 8中的18个常用日期处理(收藏)

    Java 8中的18个常用日期处理(收藏) 介绍 Java 8以前的日期处理方式比较麻烦,Java 8引入了新的日期时间API,也称为JSR-310,使对日期和时间的处理更加简便。本文将介绍Java 8中的18个常用日期处理方法。 1. 获取当天的日期 LocalDate today = LocalDate.now(); 使用LocalDate.now()方…

    Java 2023年5月20日
    00
  • springboot-jpa的实现操作

    下面是对“springboot-jpa的实现操作”的完整攻略。 一、概述 Spring Boot是一个快速开发框架,提供了很多快捷而且方便的配置方式,其中对JPA的支持也是非常好的。本攻略将介绍如何使用Spring Boot进行JPA的实现操作。 二、前提条件 在继续之前,你需要确保以下条件已满足: 你已经掌握了基本的Spring Boot使用; 你已经安装…

    Java 2023年5月20日
    00
  • javaWeb自定义标签用法实例详解

    JavaWeb自定义标签是JavaWeb开发中的一个重要组成部分,它可以方便开发人员以面向对象的方式来实现页面元素的复用和封装,加速开发效率,减少代码重复。 下面给出一个完整的JavaWeb自定义标签的攻略,包含以下内容: 1. 什么是JavaWeb自定义标签 JavaWeb自定义标签是一种特殊的JSP元素,它可以自定义页面标签,可以通过自定义标签来实现前端…

    Java 2023年6月15日
    00
  • JS、CSS加载中的小问题探讨

    我们来详细讲解“JS、CSS加载中的小问题探讨”的完整攻略。 背景 首先,我们需要了解一下JS和CSS的加载方式。在浏览器中,JS和CSS的加载是异步的,也就是说它们的加载是不阻塞页面渲染的。这也就意味着我们无法保证JS和CSS的加载顺序,可能出现JS依赖CSS但是CSS未被加载完成的情况。这时就会出现一些小问题。 问题探讨 问题一:JS依赖CSS但CSS未…

    Java 2023年6月16日
    00
  • Java实现新建有返回值的线程的示例详解

    针对“Java实现新建有返回值的线程”的问题,以下是一个完整的攻略: 1. 背景知识 在 Java 中,我们可以使用继承 Thread 类或实现 Runnable 接口来创建一个线程,具体的实现方法可以参考 “Java中创建线程的几种方式” 文章. 当我们创建一个线程时,如果需要在线程执行完毕后得到返回值,我们可以使用 Callable 接口,它定义了一个具…

    Java 2023年5月19日
    00
  • Java mysql详细讲解双数据源配置使用

    Java MySQL详细讲解双数据源配置使用攻略 在实际应用中,我们经常需要使用多个MySQL数据库,此时就需要使用双数据源配置。本文将对Java MySQL详细讲解双数据源配置使用进行攻略,希望对大家有所帮助。本攻略包括以下内容: 数据源配置 使用示例 遇到的问题及解决方案 1. 数据源配置 首先,我们需要在Spring的配置文件中进行数据源配置,这里我们…

    Java 2023年5月19日
    00
  • Java中面向对象的知识点总结

    下面我来详细讲解“Java中面向对象的知识点总结”的完整攻略。 一、面向对象的基础知识 1. 类和对象 在Java中,类是一种抽象的数据类型,用来描述具有相同属性和行为的对象的集合。而对象则是类的实例,它具有该类所描述的属性和行为。 下面是一个简单的类的定义示例: public class Person { private String name; priv…

    Java 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部