Java中的Thread类从JDK1.0开始就存在了,查阅Java API可以发现Thread类的定义:
// Thread类继承了Object类,同时实现了Runnable接口。
public class Thread
extends Object
implements Runnable
同时可以发现Thread类有一个至关重要的run()方法,这个run()方法中包含着逻辑业务代码。创建一个新的执行线程可以是将一个类声明为Thread的子类,这个子类应该重写Thread类的run()方法。
class MyThread extends Thread { // 得到了一个线程的主体类
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() { // 覆写run()方法
for (int i = 0; i < 100; i++) {
System.out.println(this.name + "运行,i = " + i);
}
}
}
现在我们自定义创建了一个线程类,继承于Thread类,覆写了run()方法,我们需要创建该类的对象,来启动run()方法,执行逻辑代码。
public class ThreadTest {
public static void main(String[] args) {
MyThread threadA = new MyThread("线程A");
MyThread threadB = new MyThread("线程B");
MyThread threadC = new MyThread("线程C");
threadA.start(); // 通过thread类继承而来
threadB.start();
threadC.start();
}
}
创建了三个线程,启动run()方法的方式是对象名.start() ,我们现运行一下看看结果,结果表明这三个线程是同时进行的,因为打印的结果中不是先把threadA的结果打印完再打印ThreadB的结果,而是掺杂着的。
所以我们也可以发现,启动run()方法是用start()方法,为什么?
首先我们查看start()方法的源代码,其中有这么两行代码:
if (threadStatus != 0)
throw new IllegalThreadStateException();
在每一个start()方法里都会抛出“IllegalThreadStateException”异常,而此异常是RuntimeException的子类,所以用户可以根据自己的需求选择性处理,此异常在重复启动多线程的时候才会抛出。这就告诉我们,启动多线程要靠start()方法,一个线程不可以同时多次使用start()方法。当然这是推理的来的证据,没有太大的说服力。
再看接着查看源代码发现:
private native void start0();
此时可以发现start()方法里面调用了一个start0()方法,而start0方法没有方法体,但是使用了native关键字处理。此关键字的作用在于此操作将交由底层实现。这里是Java虚拟机来适应不同的操作系统,运行操作系统的底层函数,启动多线程。所以start()方法的本质在于这个start0()方法。
完整代码:
class MyThread extends Thread { // 得到了一个线程的主体类
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() { // 覆写run()方法
for (int i = 0; i < 100; i++) {
System.out.println(this.name + "运行,i = " + i);
}
}
}
public class ThreadTest {
public static void main(String[] args) {
MyThread threadA = new MyThread("线程A");
MyThread threadB = new MyThread("线程B");
MyThread threadC = new MyThread("线程C");
threadA.start(); // 通过thread类继承而来
// threadA.start(); 不能同时多次使用start()方法
threadB.start();
threadC.start();
}
}