run()和start()的区别

目录

一、start:

二、 run:

三、 总结

对线程的补充:


一、start:

start()方法是Thread类定义的,也是Thread类的默认执行入口,Thread是实现Runnable接口的。通过start直接调用run()方法,启动线程,从而达到了多线程的目的(真正实现了多线程运行),这样无需等待run方法体执行完毕,直接执行下面的代码。通常系统通过调用线程的start方法启动一个线程,使线程处于就绪队列(可执行态),此时并没有运行。这就意味着该线程可以被JVM来调度执行。在调度时,JVM会通过线程的run()方法来完成试机操作,当run方法结束之后,线程终止。

下面是一个多线程并发的例子:(t1t2两个线程并发执行)

package Thread;
 
class myRunnable1 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class myRunnable2 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(-i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class demo22 {
    public static void main(String[] args) {
        Thread t1 = new Thread(new myRunnable1());
        Thread t2 = new Thread(new myRunnable2());
        t1.start();
        t2.start();
    }
}

注:由于在线程的生命周期中,线程的状态由NEW ----> RUNABLE只会发生一次,因此,一个线程只能调用start()方法一次,多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。

二、 run:

run()方法是Runnable接口中定义的, 所有实现Runnable的接口的类都需要重写run方法,run方法是一个普通方法,能够被调用,是线程默认要执行的方法,是绑定操作系统的,也是线程执行的入口。它只是一个普通的函数调用,如果直接调用run方法,程序中依然只有主线程这一个线程,其程序执行的路径还是只有一条,还是要顺序执行,要等待run方法体执行完毕后才可继续执行下面的代码。但是这样并没有达到写线程的目的。

下面一个例子:(t1和t2按照顺序执行)

package Thread;
 
class myRunnable1 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class myRunnable2 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(-i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class demo22 {
    public static void main(String[] args) {
        Thread t1 = new Thread(new myRunnable1());
        Thread t2 = new Thread(new myRunnable2());
        t1.run();
        t2.run();
    }
}

三、 总结

通过两个例子我们可以知道调用start方法可启动线程,可以并发,而run方法只是thread的一个普通方法调用,还是在主线程里执行。这里的意思就是说,star()方法可以异步地调用run()方法,是异步执行,直接调用run()方法是同步执行,因此也就不能达到多线程的目的。这两个方法应该都比较熟悉,把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用 run()方法,这是由jvm的内存机制规定的。并且run()方法必须是public访问权限,返回值类型为void。

对线程的补充:

Java 的线程是通过java.lang.Thread类来实现的。我们可以通过创建Thread的实例来创建新的线程。每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。

线程通常都有五种状态,创建、就绪、运行、阻塞和死亡

  1. 第一是创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。
  2. 第二是就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。
  3. 第三是运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码
  4. 第四是阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep(),suspend(),wait()等方法都可以导致线程阻塞。
  5. 第五是死亡状态。如果一个线程的run()方法执行结束或者调用stop()方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。

实现并启动线程有两种方法

  1. 写一个类继承自Thread类,重写run()方法。用start()方法启动线程
  2. 写一个类实现Runnable接口,实现run()方法。用new Thread(Runnable target).start()方法来启动

多线程原理:指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务。我们这里举个例子,比如玩游戏机时,只有一个游戏机(这里用游戏机代指cpu),可是有很多人要玩,于是,我们需要排队(start是排队),等CPU选中你就是轮到你,你就run(),当CPU的运行的时间片执行完,这个线程就继续排队,等待下一次的run()。

调用start()后,线程会被放到等待队列,等待CPU调度,并不一定要马上开始执行,只是将这个线程置于可动行状态。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体。先调用start后调用run,这么麻烦,为了不直接调用run?就是为了实现多线程的优点,没这个start不行。
1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态,并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的,这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。
2.run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。
记住:多线程就是分时利用CPU,宏观上让所有线程一起执行 ,也叫并发。

参考文章:https://blog.csdn.net/weixin_61061381/article/details/126053230

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
线程的run()方法和start()方法有以下区别:\[1\]\[2\]\[3\] - run()方法只是类的一个普通方法,如果直接调用run()方法,程序中只有主线程这一个线程,程序执行路径还是只有一条,需要等待run()方法执行完毕后才能继续执行下面的代码。 - start()方法是调用线程类的方法,通过调用start()方法才能真正实现多线程的目的。调用start()方法会启动一个新的线程,并使线程进入就绪状态,当分配到时间片后就可以开始运行了。start()方法会执行线程的准备工作,然后自动执行run()方法的内容,这是真正的多线程工作。 总结起来,直接调用run()方法只是在当前线程中执行run()方法的内容,而调用start()方法会启动一个新的线程,并在新的线程中执行run()方法的内容,实现了多线程的并发执行。 #### 引用[.reference_title] - *1* *2* [线程中start方法和run方法的区别](https://blog.csdn.net/qq_40649503/article/details/124556991)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [线程start() 和 run()的区别](https://blog.csdn.net/weixin_38568503/article/details/123357311)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值