跳转到内容

2. 创建新线程


Java语言内置了多线程支持。当Java程序启动的时候,实际上是启动了一个JVM进程,然后,JVM启动主线程来执行main()方法。在main()方法中,又可以启动其他线程。

要创建一个新线程非常容易,需要实例化一个Thread实例,然后调用它的start()方法。

// 多线程
public class Main {
public static void main(String[] args) {
Thread t = new Thread();
t.start(); // 启动新线程
}
}

但是这个线程启动后实际上什么也不做就立刻结束了。我们希望新线程能执行指定的代码,有以下几种方法。

  • 继承Thread:从Thread派生一个自定义类,然后覆写run()方法。
// 多线程
public class Main {
public static void main(String[] args) {
Thread t = new MyThread();
t.start(); // 启动新线程
}
}
class MyThread extends Thread {
@Overridepublic void run() {
System.out.println("start new thread!");
}
}

执行上述代码,注意到start()方法会在内部自动调用实例的run()方法。

实现 Runnable 接口,创建 Thread 实例时,传入一个 Runnable 实例。

// 多线程
public class Main {
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start(); // 启动新线程
}
}
class MyRunnable implements Runnable {
@Overridepublic void run() {
System.out.println("start new thread!");
}
}

或者用Java 8 引入的lambda语法进一步简写为:

// 多线程
public class Main {
public static void main(String[] args) {
Thread t = new Thread(() -> {
System.out.println("start new thread!");
});
t.start(); // 启动新线程
}
}

要特别注意:直接调用 Thread 实例的 run() 方法是无效的。

public class Main {
public static void main(String[] args) {
Thread t = new MyThread();
t.run();
}
}
class MyThread extends Thread {
public void run() {
System.out.println("hello");
}
}

直接调用run()方法,相当于调用了一个普通的Java方法,当前线程并没有任何改变,也不会启动新线程。

上述代码实际上是在main()方法内部又调用了run()方法,打印hello语句是在main线程中执行的,没有任何新线程被创建。

必须调用Thread实例的start()方法才能启动新线程,如果我们查看Thread类的源代码,会看到start()方法内部调用了一个private native void start0()方法,native修饰符表示这个方法是由JVM虚拟机内部的C代码实现的,不是由Java代码实现的。

  1. Java用Thread对象表示一个线程,通过调用start()启动一个新线程;
  2. 一个线程对象只能调用一次start()方法;
  3. 线程的执行代码写在run()方法中;
  4. 线程调度由操作系统决定,程序本身无法决定调度顺序;