Thread类的run()和start()方法


今天同学去面试时遇到了一个问题:一个线程在调用Thread类的start()方法之后,还能不能再继续调用start()方法,由此引起了我的一些思考。

1. 调用Thread类的start()方法后能否再调用start()方法?

答案肯定是不能的
我们来看一下例子:

public class ThreadTest {

    public static void main(String[] args){
        Thread thread = new Thread();
        thread.start();
        thread.start();
    }

}

运行结果如下:

Exception in thread "main" java.lang.IllegalThreadStateException
	at java.base/java.lang.Thread.start(Thread.java:794)

再进入start()方法,会发现有一个对线程状态的判断,当线程的状态不为0的时候,就抛出异常。这是因为当一个线程启动时,线程便会由新生状态进入就绪状态,JVM会将线程的状态由0变为1,线程在运行时的状态为2。当再次调用start()方法时,就会发现该线程并非是新生线程,从而抛出异常。

if (threadStatus != 0)
            throw new IllegalThreadStateException();

另外,我们需要注意一点,start()方法是由synchronized修饰的,所以是线程安全的。

2. run()和start()方法的区别?

该问题可谓是面试中经常会问到的问题,具体测试代码如下:

public class ThreadTest {

    public static void main(String[] args){

        System.out.println("main的线程Id:" + Thread.currentThread().getId());

        Thread thread1 = new Thread(() -> System.out.println("thread1的线程Id:" + Thread.currentThread().getId()));
        Thread thread2 = new Thread(() -> System.out.println("thread2的线程Id:" + Thread.currentThread().getId()));

        thread1.start();
        thread2.run();

    }

}

从执行结果中我们可以发现,thread1的线程Id与主线程的有所不同,而thread2的线程Id与主线程是相同的,所以我们可以判定,start()方法是新起一个线程,而run()方法只是一个普通方法,不会新起线程,而是在当前线程中执行。

main的线程Id:1
thread2的线程Id:1
thread1的线程Id:14

3. 由问题2引出,是run()方法中的代码先执行还是当前线程中的代码先执行?

具体测试代码如下:

public class ThreadTest {

    public static void main(String[] args) throws InterruptedException {

        Thread thread = new Thread(() -> System.out.println("thread的线程Id:" + Thread.currentThread().getId()));

        thread.run();
        TimeUnit.SECONDS.sleep(10);
    }

}

如果是run()方法中的代码先执行,那么应该是先打印线程Id,然后当前线线程休眠,如果是当前线程中的代码先执行,那么应该是当前线程休眠,而不会打印线程Id。实际我们可以将run()方法看出是一个普通的方法调用,因此当调用run()方法时,会先执行run()方法中的代码。
具体测试结果如下:
在这里插入图片描述

发布了8 篇原创文章 · 获赞 3 · 访问量 279

猜你喜欢

转载自blog.csdn.net/quanhong_ding/article/details/105207264