在Java 1.8及后续的版本中,我们有三种(也可以说是两种)方法开启线程。
- 继承
Thread
类 - 实现
Runnable
接口 - 使用Java 8的函数式编程
其中1和3的方式没有什么歧义,我们重点说一下Runnable
接口。
其实标题说Runnable
接口的run()
方法和start()
方法是不准确的,严格来讲,应该是Runnable
接口的run()
方法和实现Runnable
接口的实例的start()
。
先说一下结论,start()
方法来启动线程,真正实现了多线程运行。这时无需等待run
方法体代码执行完毕,可以直接继续执行下面的代码;而run()
方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码,程序中只有主线程——这一个线程,其程序执行路径还是只有一条,这样就没有达到写线程的目的。
我们可以通过下面代码进行验证。
public class Demo {
static class Runner1 implements Runnable { // 实现了Runnable接口,jdk就知道这个类是一个线程
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("进入Runner1运行状态——————————" + i);
}
}
}
static class Runner2 implements Runnable { // 实现了Runnable接口,jdk就知道这个类是一个线程
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("进入Runner2运行状态==========" + i);
}
}
}
public static void main(String[] args) {
Runner1 runner1 = new Runner1();
Runner2 runner2 = new Runner2();
runner1.run();
runner2.run();
// new Thread(runner1).start();
// new Thread(runner2).start();
}
}
看一下控制台输出内容,程序是先执行完runner1
之后才执行的runner2
方法,系统并没有给线程排队,相当于runner1
和runner2
是顺序执行的。
我们修改上面的代码,改成start()
方法执行
public class Demo {
static class Runner1 implements Runnable { // 实现了Runnable接口,jdk就知道这个类是一个线程
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("进入Runner1运行状态——————————" + i);
}
}
}
static class Runner2 implements Runnable { // 实现了Runnable接口,jdk就知道这个类是一个线程
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("进入Runner2运行状态==========" + i);
}
}
}
public static void main(String[] args) {
Runner1 runner1 = new Runner1();
Runner2 runner2 = new Runner2();
// runner1.run();
// runner2.run();
new Thread(runner1).start();
new Thread(runner2).start();
}
}
再次查看控制台
可以看到runner1
和runner2
是交替执行的,也就证明了,此时正确的开启了线程。
评论 (0)