Moosphan / Android-Daily-Interview

:pushpin:每工作日更新一道 Android 面试题,小聚成河,大聚成江,共勉之~

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2019-06-04:请谈谈 Thread 中 run() 与 start() 的区别?

Moosphan opened this issue · comments

2019-06-04:请谈谈 Thread 中 run() 与 start() 的区别?

拼写不一样

run 只是调用了Thread 的一个方法 start 是同步方法 VM创建/设置的组线程。
         

commented

start():多次启动一个线程是非法的,该方法会做检查弹出Exception;另外,该方法才会实现真正的多线程。
run():相当于调用Thread的run()而已,实质上还是在调用线程里面运行该方法。

run() 和普通的成员方法一样,可以被重复调用。但是如果单独调用 run 方法,则不是在子线程中执行。

start() 这个方法只能被调用一次。调用这个方法后 程序会启动一个 新的线程来 执行 run 方法。注意 :调用start 后,线程处于可运行状态(并没有运行),一旦得到 cup 时间片,就开始执行run 方法,run 方法结束后,线程则立即终止。

那我也补充点凑个热闹:
实现并启动线程有两种方法
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,宏观上让所有线程一起执行 ,也叫并发。

start是启动线程,run是线程中执行的方法

/**
 *
 * start()方法来启动线程,真正实现了多线程运行
 * run()方法当作普通方法的方式调用 run( )其实是一个普通方法,当线程调用了start( )方法后,一旦线程被CPU调度,处于运行状态,那么线程才会去调用这个run()方法
 */
public class MyRunTask implements Runnable {

    int count;
    public MyRunTask(int value){
        this.count = value;
    }
    @Override
    public void run() {
        System.out.println("运行run count: "+count);
    }


    public static void main(String[] args){
        //start

        Thread t1 = new Thread(new MyRunTask(2));
        Thread t2 = new Thread(new MyRunTask(3));
        t1.start();
        t2.start();
        //这个输出结果不是固定的,因为线程的运行没法预测。运行结果可能不一样。


        Thread t3 = new Thread(new MyRun2());
        Thread t4 = new Thread(new MyRun23());
        //t3.start();
        //t4.start();
        //看输出结果说明两线程是并发执行的
        //2、先用run方法启动线程 将上面的start()改为run()
        t3.run();
        t4.run();
        //明两线程实际是顺序执行的。
        //通过实例1和实例和我们可以知道start方法是用于启动线程的,可以实现并发,而run方法只是一个普通方法,是不能实现并发的,只是在并发执行的时候会调用
        //Thread类的对象其实也是一个java对象,只不过每一个Thread类的对象对应着一个线程。Thread类的对象就是提供给用户用于操作线程、获取线程的信息。真正的底层线程用户是看不到的了。
        //因此,**当一个线程结束了,死掉了,对应的Thread的对象仍能调用,除了start( )方法外的所有方法(死亡的线程不能再次启动),如run( )、getName( )、getPriority()**等等

        //http://www.cnblogs.com/jinggod/p/8485143.html
        //https://blog.csdn.net/u010568463/article/details/47911181
        //https://blog.csdn.net/xuxurui007/article/details/7685076


    }



    static class MyRun2 implements Runnable {
        public void run() {
            try {
                for(int i=0;i<10;i++){
                    System.out.println(i);
                    Thread.sleep(100);  //模拟耗时任务
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    static class MyRun23 implements Runnable {
        public void run() {
            try {
                for(int i=0;i>-10;i--){
                    System.out.println(i);
                    Thread.sleep(100);  //模拟耗时任务
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


}
``

简单的说就是 run是线程内需要执行的方法 start是线程的方法

需要记住的就是 启动线程的方法是start,启动后真正执行的方法是run

不要混淆,二者的比较意义不是很大,一个是接口的方法,一个是类的方法

2次,不是多次,(isStart){throw new Exception}

start()和run()方法除了拼写不同还有很多的区别哦😀,(对话2楼)

  • start()方法来启动线程,真正实现了多线程的运行,无需等待run()方法体执行完毕,可以直接继续执行下面的代码。
  • 通过调用Thread类的start()方法来启动一个线程,这时该线程处于就绪状态,没有真的运行。
  • 方法run()称为线程体,包含了该线程要执行的内容,此时处于运行状态,开始运行run函数中的代码,run函数结束,该线程终止。