Thread的.start()与.run()的区别
start()
start()方法启动线程,真正实现了多线程运行,无需等待方法体代码执行完毕就可以直接继续执行下面的代码。
严格来说,start()后线程进入就绪状态(ready),进入可运行线程池;之后获得CPU时间成为了运行中状态(running)。
java中将就绪和运行中状态统称为运行(RUNNABLE)。
run()
run()方法将线程体当作普通方法的方式调用,程序依然是要顺序执行。
run方法体执行完毕后才可继续执行下面的代码(实际上程序中依然只有主线程这一个线程)。
试验1
public class Try {
public static void main(String... args) {
Runnable runTask = () -> {
try {
System.out.println("sleeping...");
Thread.sleep(5000);
System.out.println("awake");
} catch (InterruptedException e) {
System.out.println("睡觉时被打");
}
};
Thread thread1 = new Thread(runTask);
Thread thread2 = new Thread(runTask);
Thread thread3 = new Thread(runTask);
thread1.start();
thread2.start();
thread3.start();
}
}
运行结果:
sleeping...
sleeping...
sleeping...
awake
awake
awake
可以看到使用start()方法时三个线程一起启动,睡5秒后一起结束。
将最后的执行部分替换成run(),再来看一下结果
thread1.run();
thread2.run();
thread3.run();
运行结果:
sleeping...
awake
sleeping...
awake
sleeping...
awake
三个线程按顺序先后执行,总计耗时15s
试验2
这个例子是为了说明,start启动的线程,确确实实是线程自己在跑,跟main()已经没关系了。
public class Try {
public static void main(String... args) throws InterruptedException {
Runnable runTask = () -> {
try {
System.out.println(Thread.currentThread().getName()
+ " - " + Thread.currentThread().getState());
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("睡觉时被打");
}
};
Thread thread = new Thread(runTask);
thread.setName("小张");
System.out.println(thread.getName() + " - " + thread.getState());
thread.start();
// 这是为了确保线程真的跑完,查看到正确的状态
Thread.sleep(2000);
System.out.println(thread.getName() + " - " + thread.getState());
}
}
运行结果:
小张 - NEW
小张 - RUNNABLE
小张 - TERMINATED
-
new Thread()以后,打印出线程处于初始状态(NEW)
(实现Runnable接口或者继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态)
-
start()方法使线程变为运行状态(RUNNABLE)
-
等待2秒后,线程确实结束,此时状态为终止(TERMINATED)
接下来仍然将start()替换为run()看一下结果:
Thread thread = new Thread(runTask);
thread.setName("小张");
System.out.println(thread.getName() + " - " + thread.getState());
thread.run();
// 这是为了确保线程真的跑完,查看到正确的状态
Thread.sleep(2000);
System.out.println(thread.getName() + " - " + thread.getState());
运行结果:
小张 - NEW
main - RUNNABLE
小张 - NEW
-
new Thread()以后,小张处于初始状态(NEW)
-
run()方法被调用后,实际的处理是main()线程自己跑的,main变成了运行状态(RUNNABLE)——即使调用的语句是thread.run(),而不是诸如main.run()
-
main将调用部分运行完毕以后,小张仍然处于初始状态(NEW),没有任何变化