run方法调用和start方法调用:
package org.example; public class MyThread2 extends Thread{ /*1:继承Thread 2:重写run方法 3:创建实例对象并且启动线程 * */ public static void main(String[] args) { MyThread2 myThread1=new MyThread2(); myThread1.start(); } @Override public void run() { for (int i=0;i<10;i++){ System.out.println("HelloWorld"); } } }
通过start方法,输出如下所示:
通过run方法,输出如下所示:
二者看着好像没啥区别,那么是不是就意味着我们既可以通过run方法调用,也可以通过start方法?
当然不是,下面我们通过多个线程来输出,看是否会出现一致的结果
package org.example; public class MyThread2 extends Thread{ /*1:继承Thread 2:重写run方法 3:创建实例对象并且启动线程 * */ public static void main(String[] args) { MyThread2 myThread2=new MyThread2(); MyThread2 myThread1=new MyThread2(); //设置线程的名字 myThread1.setName("线程1"); myThread2.setName("线程2"); myThread1.run(); myThread2.run(); } @Override public void run() { for (int i=0;i<10;i++){ System.out.println(getName()+"HelloWorld"); } } }
通过run的方式,输出如下所示:
通过start的方式,输出如下所示:
我们会发现上面二者的区别:通过start方式,两个线程是交替的执行run方法中的实现逻辑,而通过run方法,两个线程是顺序的执行run中的实现逻辑,从代码输出的角度,我们也能够看出二者之间的区别
那么实际上在Java的线程中,直接调用run()方法和调用start()方法的主要区别在于线程的执行方式。
调用run()方法会在当前线程中同步执行run()方法中的代码。这意味着,如果直接调用run()方法,线程不会启动新的线程,而是在当前线程中按照顺序执行run()方法中的代码。
而调用start()方法会启动一个新的线程,并在新的线程中异步执行run()方法中的代码。这意味着,如果调用start()方法,会创建一个新的线程来执行run()方法中的代码,而当前线程会继续执行后续的代码。
为了实现并发执行,我们必须调用start()方法来启动新的线程。如果直接调用run()方法,不会启动新的线程,而是在当前线程中按照顺序执行,这样就无法实现并发执行的效果。
需要注意的是,一个线程的start()方法只能调用一次,否则会抛出IllegalThreadStateException异常。这是因为每个线程只能启动一次。如果需要多次执行线程中的代码,可以创建多个线程对象来实现。