掘金 后端 ( ) • 2024-05-05 11:12

Java中多线程的创建方式:初学者指南

在Java编程中,多线程是一个重要的概念,它允许程序同时执行多个任务。这对于需要处理大量计算、I/O操作或响应多个用户请求的应用程序来说特别有用。本文将向初学者介绍Java中创建多线程的两种常用方式:继承Thread类和实现Runnable接口,并通过简单的示例代码和详细的注释来解释这两种方式。

1. 继承Thread类

在Java中,我们可以通过创建一个新的类来继承java.lang.Thread类来创建线程。这个新的类需要重写Thread类中的run()方法,该方法包含了线程需要执行的代码。

示例代码:

// 继承Thread类创建线程
public class MyThread extends Thread {

    // 重写Thread类的run方法
    @Override
    public void run() {
        // 线程执行的代码块
        for (int i = 0; i < 5; i++) {
            // 打印当前线程的名称和执行的次数
            System.out.println("线程 " + Thread.currentThread().getName() + " 执行: " + i);

            // 为了模拟线程执行的过程,可以添加一些延迟
            try {
                Thread.sleep(100); // 线程休眠100毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    // 主程序入口
    public static void main(String[] args) {
        // 创建MyThread对象,即创建了一个线程
        MyThread myThread = new MyThread();

        // 设置线程的名称(可选)
        myThread.setName("MyThread");

        // 启动线程,调用start()方法而不是run()方法
        myThread.start();

        // 主线程继续执行其他任务
        for (int i = 0; i < 5; i++) {
            System.out.println("主线程执行: " + i);

            try {
                Thread.sleep(100); // 主线程也休眠100毫秒,以便观察线程交替执行的效果
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

代码解释:

  • MyThread类继承了Thread类,并重写了run()方法。
  • run()方法中的代码块是线程要执行的任务。
  • main()方法中创建了MyThread对象,并通过调用start()方法来启动线程。注意,不要直接调用run()方法,因为这样会直接在当前线程中执行run()方法中的代码,而不是创建新线程来执行。
  • 通过setName()方法可以为线程设置名称,这样在输出时可以更清楚地知道是哪个线程在执行。

2. 实现Runnable接口

除了继承Thread类,Java还提供了另一种创建线程的方式:实现java.lang.Runnable接口。这种方式的好处是可以避免Java单继承的限制,因为一个类可以同时实现多个接口。

示例代码:

// 实现Runnable接口创建线程
public class MyRunnable implements Runnable {

    // 实现Runnable接口的run方法
    @Override
    public void run() {
        // 线程执行的代码块
        for (int i = 0; i < 5; i++) {
            // 打印当前线程的名称和执行的次数
            System.out.println("线程 " + Thread.currentThread().getName() + " 执行: " + i);

            // 为了模拟线程执行的过程,可以添加一些延迟
            try {
                Thread.sleep(100); // 线程休眠100毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    // 主程序入口
    public static void main(String[] args) {
        // 创建MyRunnable对象,即创建了一个可运行的任务
        MyRunnable myRunnable = new MyRunnable();

        // 使用MyRunnable对象作为参数创建Thread对象,即创建了一个线程
        Thread thread = new Thread(myRunnable, "MyRunnableThread");

        // 启动线程,调用start()方法而不是run()方法
        thread.start();

        // 主线程继续执行其他任务
        for (int i = 0; i < 5; i++) {
            System.out.println("主线程执行: " + i);

            try {
                Thread.sleep(100); // 主线程也休眠100毫秒,以便观察线程交替执行的效果
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

代码解释:

  • MyRunnable类实现了Runnable接口,并重写了run()方法。
  • run()方法中的代码块同样是线程要执行的任务。
  • main()方法中,我们创建了MyRunnable对象,该对象代表了一个可运行的任务。然后,我们使用这个MyRunnable对象作为参数创建了一个Thread对象,这个Thread对象就代表了一个线程。
  • 我们可以通过Thread类的构造函数设置线程的名称,这在new Thread(myRunnable, "MyRunnableThread")这一行代码中可以看到。
  • 接着,我们通过调用start()方法来启动线程。同样,注意不要直接调用run()方法。
  • 最后,主线程继续执行其他任务,如上面的示例代码所示。

总结

在Java中,创建线程主要有两种方式:继承Thread类和实现Runnable接口。继承Thread类的方式简单直接,但受限于Java的单继承机制;而实现Runnable接口的方式则更加灵活,一个类可以同时实现多个接口,因此更常用。

无论使用哪种方式,都需要重写run()方法来定义线程要执行的任务。启动线程时,应该调用start()方法而不是run()方法,因为start()方法会创建一个新的线程来执行run()方法中的代码,而直接调用run()方法则会在当前线程中执行代码。

希望这篇文章能帮助初学者更好地理解Java中多线程的创建方式,并为后续的深入学习打下坚实的基础。