调用start()后会执行run(),为什不直接调用run?,
刚开始学线程的时候,总是把run方法和start方法搞混。虽然两种方法完全不同,但是第一次用的时候很难区分。原因是你第一次使用它们时,效果似乎是一样的。
如下代码所示:
public static void main(string[]args){//Create thread one thread thread=new thread(new runnable(){ @ override public void run(){ system . out . println( execution thread one );} });//调用运行方法thread . run();//创建线程二thread thread 2=new thread(newrunnable(){ @ override public void run(){ system . out . println( thread two );} });//调用start方法thread 2 . start();}以上程序的执行结果如下:
从上面的结果可以看出,两个调用的执行效果是一样的,都可以成功执行任务。但是,如果在执行线程时打印当前线程的名称,就可以看出它们之间的区别。
如下代码所示:
public static void main(string[]args){//Create thread-thread=new thread(new runnable(){ @ override public void run(){//Get thread curr thread=thread . current thread()当前执行线程;System.out.println(执行线程一,线程名: curr thread . getname()));} });//调用运行方法thread . run();//创建线程二thread thread thread 2=new thread(newrunnable(){ @ override public void run(){//获取当前执行线程的线程curr thread=thread . curr thread();System.out.println (thread 2,线程名: curr thread . getname()));} });//调用start方法thread 2 . start();}以上程序的执行结果如下:
从上述结果我们可以看出:调用run方法时,实际上是调用当前主程序main来执行方法体;调用start方法实际上是创建一个新的线程来执行任务。
00-1010run 方法和 start 方法的第一个区别是:调用start方法真正启动一个线程执行一个任务,而调用run方法相当于执行普通的方法run,并不启动一个新的线程。
如下图所示:
00-1010run方法与start方法的第二个区别是,run方法也被称为线程体,它包含了要执行的具体业务代码。当run方法被调用时,RUN方法中的代码会被立即执行(如果当前线程时间片没有用完);当调用start方法时,它启动一个线程,并将线程的状态设置为就绪状态。也就是说,调用start方法不会立即执行。
00-1010因为run方法是普通方法,而且普通方法可以多次调用,所以run方法可以多次调用;start方法是创建一个新的线程来执行任务,因为线程只能创建一次,所以它们的第三个区别是:run 方法可以被调用多次,而 start 方法只能被调用一次。
测试代码如下:
//Create thread one thread thread=new thread(new runnable(){ @ override public VO
id run() { // 获取到当前执行的线程 Thread currThread = Thread.currentThread(); System.out.println("执行线程一,线程名:" + currThread.getName()); }});// 调用 run 方法thread.run();// 多次调用 run 方法thread.run();// 创建线程二Thread thread2 = new Thread(new Runnable() { @Override public void run() { // 获取到当前执行的线程 Thread currThread = Thread.currentThread(); System.out.println("执行线程二,线程名:" + currThread.getName()); }});// 调用 start 方法thread2.start();// 多次调用 start 方法thread2.start();以上程序的执行结果如下:
从上述结果可以看出,run 方法多次调用可用正常执行,而第二次调用 start 方法时程序就报错了,提示IllegalThreadStateException非法线程状态异常。
为什么start不能被重复调用?
要找到这个问题的答案,就要查看 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中为什么start方法不能重复调用而run方法可以?的文章就介绍到这了,更多相关start与run方法内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。