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
异常。这是因为每个线程只能启动一次
。如果需要多次执行线程中的代码,可以创建多个线程对象来实现。