刚开始学习线程的时候,总是把run方法和start方法搞混。虽然两者是完全不同的方法,但一开始很难区分。原因是第一次使用效果好像一样。如下代码所示:publicstaticvoidmain(String[]args){//创建线程一Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){System.out.println("Execute线程一");}});//调用运行方法thread.run();//创建线程2Threadthread2=newThread(newRunnable(){@Overridepublicvoidrun(){System.out.println("ExecutionThread2");}});//调用start方法thread2.start();}以上程序的执行结果如下:从上面的结果可以看出,两次调用的执行效果是一样的,都可以执行任务成功。但是,如果在执行线程时打印当前线程的名称,就可以看出两者的区别,如下代码所示:publicstaticvoidmain(String[]args){//创建一个线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){//获取当前执行线程ThreadcurrThread=Thread.currentThread();System.out.println("执行线程一,线程名:"+currThread.getName());}});//调用运行方法thread.run();//创建线程2Threadthread2=newThread(newRunnable(){@Overridepublicvoidrun(){//获取当前执行线程ThreadcurrThread=Thread.currentThread();System.out.println("执行线程二,线程名称:"+currThread.getName());}});//调用启动方法thread2.start();}上面程序的执行结果如下:从上面的结果我们可以看出,在调用run方法的时候,实际上是调用了当前主程序main来执行方法体;而start方法实际上是创建一个新的线程来执行任务。区别1run方法和start方法的第一个区别是:调用start方法实际上是启动一个线程执行任务,而调用run方法相当于执行普通方法run,不会启动新的线程,如下图所示:区别2run方法和start方法的第二个区别是:run方法也叫线程体,里面包含了具体要执行的业务代码。当调用run方法时,会立即执行run方法中的代码(如果当前线程时间片没有Exhausted);当调用start方法时,会启动一个线程,并将该线程的状态设置为就绪状态。也就是说调用start方法不会立即执行。区别3因为run方法是普通方法,而普通方法可以调用多次,所以run方法可以调用多次;而start方法是创建一个新的线程来执行任务,因为线程只能创建一次,所以它们的第三个区别是:run方法可以调用多次,而start方法只能调用一次。测试代码如下://创建一个线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){//获取当前正在执行的线程ThreadcurrThread=Thread.currentThread();System.out.println("执行线程一,线程名:"+currThread.getName());}});//调用run方法thread.run();//多次调用run方法thread.run();//创建一个线程TwoThreadthread2=newThread(newRunnable(){@Overridepublicvoidrun(){//获取当前正在执行的线程ThreadcurrThread=Thread.currentThread();System.out.println("执行线程二、线程名称:"+currThread.getName());}});//调用启动方法thread2.start();//多次调用启动方法thread2.start();上面程序的执行结果如下:从上面的结果我们可以看出run方法可以被调用多次,可以正常执行,但是当start方法执行的时候程序报错第二次调用,提示“IllegalThreadStateException”非法线程状态异常。为什么不能开始重复调用?要找到这个问题的答案,我们需要查看start方法的实现源码。它的源码如下:从start源码实现的第一行,我们可以得到问题的答案,因为start方法在执行的时候,会先判断当前线程的状态是否等于0,即就是,是否是新状态NEW,如果不等于新状态,那么就会抛出“IllegalThreadStateException”非法线程状态异常,这就是线程的start方法不能重复调用的原因。它的执行过程是:当线程调用第一个start方法时,线程的状态会从新建状态NEW变为就绪状态RUNNABLE。此时如果再次调用start方法,JVM会判断当前线程不再等于新的状态,从而抛出IllegalThreadStateException非法线程状态异常。总结一下run方法和start方法的主要区别如下:方法本质不同:run是普通方法,start是启动新线程的方法。执行速度不同:调用run方法会立即执行任务,调用start方法会将线程状态变为就绪状态,不会立即执行。调用次数不同:run方法可以重复调用,而start方法只能调用一次。之所以不能重复调用start方法,是因为线程的状态是不可逆的。Thread在start的实现源码中进行了判断。如果线程不处于NEW的新状态,将抛出非法线程状态异常IllegalThreadStateException。判断是非在己,名誉在人,得失在数。公众号:Java面试真题分析面试合集:https://gitee.com/mydb/interview
