【Java】详细介绍Java实现线程的四种方式


在Java中,有多种方式可以实现多线程,本文将介绍其中的4种方式

  • 继承Thread类
  • 实现Runnable接口
  • 实现Callable接口
  • 使用线程池

1.继承Thread类

继承Thread类是实现多线程的一种常见方式。我们只需要重写Thread类中的run()方法,并在其中实现需要执行的代码。下面是一个示例:

  1. 创建一个类并继承Thread类。
  2. 重写run()方法,定义线程要执行的任务。
  3. 创建该类的实例并调用start()方法启动线程。

创建线程:

public class MyThread extends Thread {
    
    
    public void run() {
    
    
        System.out.println("线程开始执行");
        // TODO: 执行需要执行的代码
        System.out.println("线程执行结束");
    }
}

调用线程:

public class Main {
    
    
    public static void main(String[] args) {
    
    
        MyThread thread = new MyThread();
        thread.start();
    }
}

2.实现Runnable接口

实现Runnable接口是另一种实现多线程的方式,这种方式比继承Thread类更加灵活,因为一个类可以同时实现多个接口。下面是一个示例:

  1. 创建一个类并实现Runnable接口。
  2. 重写run()方法,定义线程要执行的任务。
  3. 创建该类的实例并将其作为Thread类的构造函数的参数。
  4. 调用start()方法启动线程。
public class MyRunnable implements Runnable {
    
    
    public void run() {
    
    
        System.out.println("线程开始执行");
        // TODO: 执行需要执行的代码
        System.out.println("线程执行结束");
    }
}
public class Main {
    
    
    public static void main(String[] args) {
    
    
        MyRunnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
    }
}

补充:Java8中使用匿名内部类和Lambda表达式方法创建线程

// 使用匿名类创建线程
new Thread(new Runnable() {
    
    
    public void run() {
    
    
        System.out.println("This is a new thread.");
    }
}).start();

// 使用Lambda表达式创建线程
new Thread(() -> {
    
    
    System.out.println("This is a new thread.");
}).start();

3.实现Callable接口

与实现Runnable接口类似,实现Callable接口也是一种实现多线程的方式。不同的是,Callable接口的call()方法可以返回一个值,并且可以抛出异常。下面是一个示例:

  1. 创建一个类并实现Callable接口。
  2. 重写call()方法,定义线程要执行的任务并返回一个结果。
  3. 创建该类的实例并将其作为FutureTask类的构造函数的参数。
  4. 创建一个线程并将FutureTask实例作为参数传递。
  5. 调用start()方法启动线程。
  6. 调用get()方法获取结果。
public class MyCallable implements Callable<Integer> {
    
    
    public Integer call() throws Exception {
    
    
        System.out.println("线程开始执行");
        // TODO: 执行需要执行的代码
        System.out.println("线程执行结束");
        return 0;
    }
}
public class Main {
    
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
        MyCallable callable = new MyCallable();
        FutureTask<Integer> task = new FutureTask<>(callable);
        Thread thread = new Thread(task);
        thread.start();
        Integer result = task.get();
    }
}

4. 使用线程池实现

线程池是用来维护和控制线程的,它可以循环使用线程,降低了线程的创建和销毁的频率,提高了程序的运行效率。在使用线程池时,我们可以直接提交任务给线程池,线程池会自动分配线程去执行任务,无需我们手动创建和管理线程。下面是示例:

示例1:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    
    
    public static void main(String[] args) {
    
    
        // 创建线程池,其中参数为线程池大小
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        // 创建Runnable任务
        Runnable task = new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("Thread " + Thread.currentThread().getName() + " is running.");
            }
        };

        // 提交任务到线程池中执行
        for (int i = 0; i < 5; i++) {
    
    
            executorService.submit(task);
        }

        // 关闭线程池
        executorService.shutdown();
    }
}

运行结果:

Thread pool-1-thread-1 is running.
Thread pool-1-thread-3 is running.
Thread pool-1-thread-2 is running.
Thread pool-1-thread-3 is running.
Thread pool-1-thread-1 is running.

在这个例子中,我们首先创建了一个线程池,使用 Executors.newFixedThreadPool() 方法,指定了线程池的大小为 3。然后,我们创建了一个 Runnable 任务,并使用 executor.submit() 方法将该任务提交到线程池中执行。最后,我们关闭了线程池,使用 executor.shutdown() 方法。

在执行过程中,我们可以看到每个任务都会被线程池中的某个线程执行,并输出该线程的名称。由于线程池大小为 3,因此最多会有 3 个任务同时被执行,其他任务会等待线程池中的线程空闲后再执行。

示例2 (Lambda表达式):

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    
    

    public static void main(String[] args) {
    
    
        // 创建一个线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for(int i =0; i<3;i++)
        // 提交一个任务给线程池执行
        executorService.submit(() -> {
    
    
            System.out.println("线程开始执行");
            // TODO: 执行需要执行的代码
            System.out.println("线程执行结束");

        });

        // 关闭线程池
        executorService.shutdown();
    }
}

猜你喜欢

转载自blog.csdn.net/AwesomeP/article/details/130175736