Java中的线程由java.lang.Thread
类表示。当我们创建一个线程并调用其start()
方法时,Java虚拟机(JVM)会为该线程分配执行资源并开始执行该线程的run()
方法。
以下是Java线程启动和执行run()
方法的基本流程:
- 创建一个
Thread
对象或其子类的对象。这通常涉及到定义一个run()
方法。 - 调用该对象的
start()
方法。 start()
方法通知JVM创建一个新的线程并开始执行。- JVM调用
run()
方法。
使用流程图表示如下:
sql
+-------------------+
| Create Thread obj |
+-------------------+
|
v
+-------------------+
| Call start() |
+-------------------+
|
v
+-------------------+
| JVM allocates |
| execution resources|
+-------------------+
|
v
+-------------------+
| JVM calls run() |
+-------------------+
重要点:
- 只有通过调用
start()
方法,JVM才会为线程分配必要的资源并执行run()
方法。直接调用run()
方法不会启动新的线程,而只是在当前线程中执行run()
方法。 - 每个
Thread
对象只能被start()
一次。多次调用会抛出IllegalThreadStateException
。
最佳实践是,不要直接继承Thread
类来创建线程,而是实现Runnable
接口,并将其传递给Thread
的构造函数。这种方法更加灵活,允许你更容易地重用代码和合并资源。
在Java中,主要有两种方法创建多线程:
-
继承
Thread
类:-
步骤:
- 定义一个类继承
Thread
类。 - 重写
run()
方法。 - 创建该类的实例。
- 调用该实例的
start()
方法。
- 定义一个类继承
-
示例:
typescriptclass MyThread extends Thread { public void run() { System.out.println("Thread is running"); } } public class Test { public static void main(String[] args) { MyThread t = new MyThread(); t.start(); } }
-
优点:
- 简单,对于小项目或快速原型设计来说容易实现。
-
缺点:
- Java不支持多重继承。如果一个类已经继承了其他类,那么它不能再继承
Thread
类。 - 不利于代码复用。继承了
Thread
类的类只能当作线程使用,而不能当作普通的类使用。
- Java不支持多重继承。如果一个类已经继承了其他类,那么它不能再继承
-
-
实现
Runnable
接口:-
步骤:
- 定义一个类实现
Runnable
接口。 - 重写
run()
方法。 - 创建
Thread
类的实例,并传入Runnable
对象。 - 调用
Thread
实例的start()
方法。
- 定义一个类实现
-
示例:
typescriptclass MyRunnable implements Runnable { public void run() { System.out.println("Thread is running"); } } public class Test { public static void main(String[] args) { MyRunnable r = new MyRunnable(); Thread t = new Thread(r); t.start(); } }
-
优点:
- 更加灵活。由于Java支持多接口继承,所以一个类可以实现多个接口,包括
Runnable
。 - 更易于代码复用。可以独立于线程机制,作为一个普通的类被复用。
- 与线程的行为解耦。线程的行为(如优先级、守护状态等)由
Thread
类控制,任务的行为由Runnable
对象控制。
- 更加灵活。由于Java支持多接口继承,所以一个类可以实现多个接口,包括
-
缺点:
- 需要额外创建
Thread
对象,这在某些情况下可能会增加轻微的复杂性。
- 需要额外创建
-
总结:
尽管可以通过继承Thread
类来创建线程,但大多数情况下,实现Runnable
接口是更好的选择,因为它提供了更大的灵活性和更好的代码复用性。另外,Java提供的Executor
框架也推荐使用Runnable
或其更灵活的版本,Callable
,来定义并行任务。