多线程中的run方法和start方法有什么区别?

简介: 多线程中的run方法和start方法有什么区别?

run方法调用和start方法调用:

package org.example;
public class MyThread2 extends Thread{
    /*1:继承Thread
    2:重写run方法
    3:创建实例对象并且启动线程
    * */
    public static void main(String[] args) {
        MyThread2 myThread1=new MyThread2();
        myThread1.start();
    }
    @Override
    public void run() {
        for (int i=0;i<10;i++){
            System.out.println("HelloWorld");
        }
    }
}

通过start方法,输出如下所示:

通过run方法,输出如下所示:

二者看着好像没啥区别,那么是不是就意味着我们既可以通过run方法调用,也可以通过start方法?

当然不是,下面我们通过多个线程来输出,看是否会出现一致的结果

package org.example;
public class MyThread2 extends Thread{
    /*1:继承Thread
    2:重写run方法
    3:创建实例对象并且启动线程
    * */
    public static void main(String[] args) {
        MyThread2 myThread2=new MyThread2();
        MyThread2 myThread1=new MyThread2();
        //设置线程的名字
        myThread1.setName("线程1");
        myThread2.setName("线程2");
        myThread1.run();
        myThread2.run();
    }
    @Override
    public void run() {
        for (int i=0;i<10;i++){
            System.out.println(getName()+"HelloWorld");
        }
    }
}

通过run的方式,输出如下所示:

通过start的方式,输出如下所示:

我们会发现上面二者的区别:通过start方式,两个线程是交替的执行run方法中的实现逻辑,而通过run方法,两个线程是顺序的执行run中的实现逻辑,从代码输出的角度,我们也能够看出二者之间的区别


那么实际上在Java的线程中,直接调用run()方法和调用start()方法的主要区别在于线程的执行方式。


调用run()方法会在当前线程中同步执行run()方法中的代码。这意味着,如果直接调用run()方法,线程不会启动新的线程,而是在当前线程中按照顺序执行run()方法中的代码。


而调用start()方法会启动一个新的线程,并在新的线程中异步执行run()方法中的代码。这意味着,如果调用start()方法,会创建一个新的线程来执行run()方法中的代码,而当前线程会继续执行后续的代码。


为了实现并发执行,我们必须调用start()方法来启动新的线程。如果直接调用run()方法,不会启动新的线程,而是在当前线程中按照顺序执行,这样就无法实现并发执行的效果。


需要注意的是,一个线程的start()方法只能调用一次,否则会抛出IllegalThreadStateException异常。这是因为每个线程只能启动一次。如果需要多次执行线程中的代码,可以创建多个线程对象来实现。

相关文章
|
26天前
|
存储 Java 程序员
优化Java多线程应用:是创建Thread对象直接调用start()方法?还是用个变量调用?
这篇文章探讨了Java中两种创建和启动线程的方法,并分析了它们的区别。作者建议直接调用 `Thread` 对象的 `start()` 方法,而非保持强引用,以避免内存泄漏、简化线程生命周期管理,并减少不必要的线程控制。文章详细解释了这种方法在使用 `ThreadLocal` 时的优势,并提供了代码示例。作者洛小豆,文章来源于稀土掘金。
|
2月前
|
算法 安全 Java
三种方法教你实现多线程交替打印ABC,干货满满!
本文介绍了多线程编程中的经典问题——多线程交替打印ABC。通过三种方法实现:使用`wait()`和`notify()`、`ReentrantLock`与`Condition`、以及`Semaphore`。每种方法详细讲解了实现步骤和代码示例,帮助读者理解和掌握线程间的同步与互斥,有效解决并发问题。适合不同层次的开发者学习参考。
44 11
|
28天前
|
Java Spring
运行@Async注解的方法的线程池
自定义@Async注解线程池
50 3
|
2月前
|
安全 Java API
WK
|
20天前
|
并行计算 调度 Python
GIL和线程之间的区别是什么
全局解释器锁(GIL)与线程在Python中具有不同角色。GIL作为CPython中的互斥锁,确保同一时间只有一个线程执行Python字节码,简化内存管理但限制多线程并行性;线程则是程序执行的最小单位,允许多个任务并发运行。GIL影响整个解释器,使多线程串行化;线程则代表独立执行流,受GIL制约。GIL在计算密集型任务中成为瓶颈,但在I/O密集型任务中多线程仍可提升性能。理解两者差异有助于优化多线程应用。
WK
23 0
|
2月前
|
消息中间件 资源调度 调度
进程与线程的区别
【8月更文挑战第24天】
22 0
|
2月前
|
消息中间件 安全 Java
Java 中的线程与进程之区别
【8月更文挑战第22天】
71 0
|
2月前
|
算法 Java
【多线程面试题十八】、说一说Java中乐观锁和悲观锁的区别
这篇文章讨论了Java中的乐观锁和悲观锁的区别,其中悲观锁假设最坏情况并在访问数据时上锁,如通过`synchronized`或`Lock`接口实现;而乐观锁则在更新数据时检查是否被其他线程修改,适用于多读场景,并常通过CAS操作实现,如Java并发包`java.util.concurrent`中的类。
|
2月前
|
存储 监控 Java
Java多线程优化:提高线程池性能的技巧与实践
Java多线程优化:提高线程池性能的技巧与实践
63 1
|
1天前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口