java创建线程的三种方法(非常详细,附带示例)
在 Java 程序中,创建线程的方法有种,分别是:
接下来将展开讲解这种方法。
【实例】继承 Thread 类,创建线程并启动线程,代码如下:
MyThreadDemo 类重写了 Thread 类的 run() 方法,该方法定义了线程被调度执行时所需完成的任务。而在 ThreadDemoTest 类中,为了启动这个自定义线程,必须调用其 start() 方法。
采用继承 Thread 类创建线程的方法,需要注意以下几点:

图 1 线程启动流程
Java 核心类库提供 Runnable 接口,这一机制允许通过实现 Runnable 接口并重写其 run() 方法来定义线程的执行体。随后,我们可以用 Thread 类的对象作为代理,启动并执行自定义的 run() 方法,从而灵活地实现多线程编程。
下面是实现 Runnable 接口的具体流程:
【实例】实现 Runnable 接口,创建线程并启动线程,代码如下:
重要的是,MyThreadDemo 并非直接代表线程对象本身,而是作为线程任务的一个载体或对象存在。实际的线程对象需要在 RunnableDemoTest 类中通过适当的构造进行创建,随后通过调用 start() 方法来启动这一线程,从而执行在 MyThreadDemo 类中定义的 run() 方法内的任务。
实现 Runnable 接口避免了单继承的局限性,多个线程可以共享同一个接口实现类的对象,非常适合多个相同的线程来使用同一资源的情况。多线程可以增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
实现 Runnable 接口创建线程,需要注意以下几点:
【实例】使用匿名内部类对象创建线程并启动线程,代码如下:
而在 testRunn() 方法中,创建线程的方式依赖实现 Runnable 接口的类,我们同样需要重写 run() 方法来指定线程的任务内容,但启动线程的方式稍有不同。这里是通过 Thread 类的构造器传入实现 Runnable 接口的实例,并调用其 start() 方法来启动线程。
- 继承 Thread 类,创建线程并启动线程;
- 实现 Runnable 接口,创建线程并启动线程;
- 使用匿名内部类对象,实现对线程的创建和启动。
接下来将展开讲解这种方法。
继承Thread类
Java 通过继承 Thread 类来创建并启动多线程,下面是具体的实现流程:- 定义 Thread 类的子类,并重写该类的 run() 方法,该 run() 方法的方法体代表线程需要完成的任务;
- 创建 Thread 子类的实例,即创建线程对象;
- 调用线程对象的 start() 方法来启动该线程。
【实例】继承 Thread 类,创建线程并启动线程,代码如下:
/** * 自定义线程继承 Thread 类 */ public class MyThreadDemo extends Thread { // 定义指定线程名称的构造方法 public MyThreadDemo(String name) { // 调用父类的 String 参数的构造方法,指定线程的名称 super(name); } /** * 重写 run 方法,实现该线程执行的逻辑 */ public void run() { for (int i = 0; i < 10; i++) { System.out.println(getName() + ":正在执行!" + i); } } } public class ThreadDemoTest { public static void main(String[] args) { // 创建自定义线程对象1 MyThreadDemo myThreadDemo = new MyThreadDemo("线程 1"); // 启动线程1 myThreadDemo.start(); // 创建自定义线程对象2 MyThreadDemo myThreadDemo02 = new MyThreadDemo("线程 2"); // 启动线程2 myThreadDemo02.start(); // 在 main 方法中执行 for 循环 for (int i = 1; i <= 10; i++) { System.out.println("main 线程:" + i); } } }在上述代码中,MyThreadDemo 类通过继承 Thread 类实现了对自定义线程的创建。
MyThreadDemo 类重写了 Thread 类的 run() 方法,该方法定义了线程被调度执行时所需完成的任务。而在 ThreadDemoTest 类中,为了启动这个自定义线程,必须调用其 start() 方法。
采用继承 Thread 类创建线程的方法,需要注意以下几点:
- 如果手动调用 run() 方法,那么它就是一个普通的 Java 方法,并不会启动多线程模式。
- run() 方法通常由 JVM 在特定时刻内调用,而调用的时机以及对执行过程的控制,完全由操作系统对 CPU 的调度决定。
- 启动多线程,必须调用线程的 start() 方法。
- 一个线程对象只能被调用一次 start() 方法来启动,若尝试重复调用,则会抛出 IllegalThreadStateException 异常。
- 线程启动流程,如下图所示:

图 1 线程启动流程
实现Runnable接口
Java 具有单继承限制,当无法直接继承 Thread 类时,应该如何应对?Java 核心类库提供 Runnable 接口,这一机制允许通过实现 Runnable 接口并重写其 run() 方法来定义线程的执行体。随后,我们可以用 Thread 类的对象作为代理,启动并执行自定义的 run() 方法,从而灵活地实现多线程编程。
下面是实现 Runnable 接口的具体流程:
- 定义 Runnable 接口的实现类,并重新实现该接口的 run() 方法。该 run() 方法的具体实现即该线程的线程执行体。
- 创建 Runnable 接口实现类的实例,并将该实例作为 Thread 类的 target 参数来构造 Thread 对象。这个 Thread 对象即真正的线程实体。
- 通过调用线程对象的 start() 方法来启动线程。注意,不应该直接调用 Runnable 接口实现类的 run() 方法,因为这样做并不会启动一个新的线程,而是像调用普通方法一样在当前线程中执行 run() 方法的内容。
【实例】实现 Runnable 接口,创建线程并启动线程,代码如下:
public class MyThreadDemo implements Runnable { @Override public void run() { for (int i = 0; i < 20; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } } } public class RunnableDemoTest { public static void main(String[] args) { // 创建自定义的对象,线程任务对象 MyThreadDemo myThreadDemo02 = new MyThreadDemo(); // 创建线程对象 Thread thread = new Thread(myThreadDemo02); // 启动线程对象 thread.start(); for (int i = 0; i < 10; i++) { System.out.println("chapter13: " + i); } } }在上述代码中,MyThreadDemo 类通过实现 Runnable 接口,并覆写(重写)其 run() 方法来定义线程的执行任务。
重要的是,MyThreadDemo 并非直接代表线程对象本身,而是作为线程任务的一个载体或对象存在。实际的线程对象需要在 RunnableDemoTest 类中通过适当的构造进行创建,随后通过调用 start() 方法来启动这一线程,从而执行在 MyThreadDemo 类中定义的 run() 方法内的任务。
实现 Runnable 接口避免了单继承的局限性,多个线程可以共享同一个接口实现类的对象,非常适合多个相同的线程来使用同一资源的情况。多线程可以增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
实现 Runnable 接口创建线程,需要注意以下几点:
- 通过实现 Runnable 接口,相应的类便具备了多线程特性。所有需要在分线程中执行的代码都应当被置于 run() 方法之内。
- 在启动多线程时,需要利用 Thread 类的构造方法 Thread(Runnable target) 来创建一个 Thread 对象,并指定 Runnable 接口的实现类作为参数。随后,通过调用该 Thread 对象的 start() 方法来启动并执行多线程代码。
- 实际上,无论是继承 Thread 类,还是实现 Runnable 接口,最终都是依赖 Thread 对象的 API 来控制线程的。因此,熟悉 Thread 类的 API 是进行多线程编程不可或缺的基础。
- Runnable 对象在这里仅作为 Thread 对象的 target 参数存在,而 Runnable 接口实现类中的 run() 方法则充当了线程的执行体。尽管实际的线程对象是 Thread 的实例,但正是这个 Thread 线程负责执行其 target 参数指定的 run() 方法中的代码。
匿名内部类创建启动线程
我们使用匿名内部类对象,实现对线程的创建和启动。【实例】使用匿名内部类对象创建线程并启动线程,代码如下:
public class AnonymousDemoTest { public static void main(String[] args) { AnonymousDemoTest anonymousDemoTest = new AnonymousDemoTest(); anonymousDemoTest.testThread(); anonymousDemoTest.testRunn(); } /** * 使用匿名内部类创建线程类,调用 start() 方法,启动线程 */ public void testThread() { new Thread() { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(getName() + ":正在执行!" + i); } } }.start(); } /** * 使用匿名内部类创建线程类,调用 start() 方法,启动线程 */ public void testRunn() { new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } } }).start(); } }在 testThread() 方法中,我们直接运用了 Thread 类来实例化一个线程对象,通过重写其 run() 方法来定义线程的执行任务,随后调用 start() 方法来启动线程的执行。
而在 testRunn() 方法中,创建线程的方式依赖实现 Runnable 接口的类,我们同样需要重写 run() 方法来指定线程的任务内容,但启动线程的方式稍有不同。这里是通过 Thread 类的构造器传入实现 Runnable 接口的实例,并调用其 start() 方法来启动线程。