创建线程的8种方法

创建线程的8种方法

目录

  1. 继承Thread类
  2. 实现Runnable接口
  3. 实现Callable接口
  4. 使用线程池
  5. 使用ScheduledExecutorService
  6. 使用Fork/Join框架
  7. 使用CompletableFuture
  8. 使用Guava的ListenableFuture
  9. 总结

1. 继承Thread类

最直接的方式是创建一个继承自Thread类的子类,并重写其run()方法。

示例代码:

java 复制代码
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程名称:" + Thread.currentThread().getName() + " 正在执行任务");
    }
}

public class ThreadExample {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        thread1.start(); // 启动线程
        thread2.start();
    }
}

优点: 简单直观,适合初学者。 缺点: 扩展性差,因为Java不支持多继承。

2. 实现Runnable接口

更灵活的方式是实现Runnable接口,将任务逻辑放在run()方法中。

示例代码:

java 复制代码
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("线程名称:" + Thread.currentThread().getName() + " 正在执行任务");
    }
}

public class RunnableExample {
    public static void main(String[] args) {
        Thread thread1 = new Thread(new MyRunnable());
        Thread thread2 = new Thread(new MyRunnable());
        thread1.start();
        thread2.start();
    }
}

优点: 解耦任务逻辑和线程对象,灵活性更高。 缺点: 需要额外创建Thread对象。

3. 实现Callable接口

Callable接口与Runnable类似,但它支持返回值和抛出异常。

示例代码:

java 复制代码
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "线程名称:" + Thread.currentThread().getName() + ",任务执行完成";
    }
}

public class CallableExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
        Thread thread = new Thread(futureTask);
        thread.start();

        // 获取线程返回结果
        System.out.println("线程返回结果:" + futureTask.get());
    }
}

优点: 支持返回值和异常处理。 缺点: 代码复杂度略高。

4. 使用线程池

线程池是一种高效的线程管理机制,可以复用线程,减少开销。

示例代码:

java 复制代码
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 task = () -> System.out.println("线程名称:" + Thread.currentThread().getName() + " 正在执行任务");

        for (int i = 0; i < 5; i++) {
            executorService.execute(task);
        }

        executorService.shutdown();
    }
}

优点: 高效管理线程生命周期。 缺点: 需要合理配置线程池参数。

5. 使用ScheduledExecutorService

ScheduledExecutorService用于定时或周期性执行任务。

示例代码:

java 复制代码
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledExample {
    public static void main(String[] args) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        Runnable task = () -> System.out.println("当前时间:" + System.currentTimeMillis());

        // 延迟1秒后,每2秒执行一次
        scheduler.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS);

        // 程序运行一段时间后需要手动关闭线程池
        // scheduler.shutdown();
    }
}

优点: 易于实现定时和周期性任务。 缺点: 不适合复杂调度场景。

6. 使用Fork/Join框架

Fork/Join框架适合将大任务分解成多个子任务并行处理。

示例代码:

java 复制代码
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;

class SumTask extends RecursiveTask<Integer> {
    private final int start, end;

    public SumTask(int start, int end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        if (end - start <= 10) {
            int sum = 0;
            for (int i = start; i <= end; i++) {
                sum += i;
            }
            return sum;
        } else {
            int mid = (start + end) / 2;
            SumTask leftTask = new SumTask(start, mid);
            SumTask rightTask = new SumTask(mid + 1, end);
            invokeAll(leftTask, rightTask);
            return leftTask.join() + rightTask.join();
        }
    }
}

public class ForkJoinExample {
    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool();
        SumTask task = new SumTask(1, 100);
        System.out.println("总和:" + pool.invoke(task));
    }
}

优点: 提高低核CPU的利用率。 缺点: 不适合I/O密集型任务。

7. 使用CompletableFuture

CompletableFuture支持异步编程,适合复杂任务的分解与组合。

示例代码:

java 复制代码
import java.util.concurrent.CompletableFuture;

public class CompletableFutureExample {
    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> {
            System.out.println("任务执行:" + Thread.currentThread().getName());
            return "任务结果";
        }).thenApply(result -> {
            System.out.println("处理结果:" + result);
            return "最终结果";
        }).thenAccept(System.out::println);
    }
}

优点: 功能强大,代码简洁。 缺点: 学习成本较高。

8. 使用Guava的ListenableFuture

Guava的ListenableFuture是对Future的增强,支持任务完成后的回调处理。

示例代码:

java 复制代码
import com.google.common.util.concurrent.*;
import java.util.concurrent.Executors;

public class ListenableFutureExample {
    public static void main(String[] args) {
        ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(2));

        ListenableFuture<String> future = service.submit(() -> {
            Thread.sleep(1000);
            return "任务完成";
        });

        Futures.addCallback(future, new FutureCallback<String>() {
            @Override
            public void onSuccess(String result) {
                System.out.println("任务成功,结果:" + result);
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println("任务失败:" + t.getMessage());
            }
        }, service);

        service.shutdown();
    }
}

优点: 回调机制强大,扩展性好。 缺点: 引入了第三方依赖。

总结

以上就是Java中创建线程的8种方法,每一种方法都有其适用场景和优缺点。希望大家在实际开发中,能根据场景选择合适的方式。例如,小任务可以用Runnable,复杂计算可以用Callable,高并发场景可以用线程池,而异步任务可以用CompletableFuture或ListenableFuture等。通过这些方法的组合,可以让你的代码更加高效、优雅!

相关推荐
nlog3n1 小时前
Java策略模式详解
java·bash·策略模式
兰琛1 小时前
Compose组件转换XML布局
android·xml·kotlin
Qlittleboy2 小时前
windows如何安装wkhtmltoimage 给PHP使用根据HTML生成图片
开发语言·windows·php
水w3 小时前
【Android Studio】解决报错问题Algorithm HmacPBESHA256 not available
android·开发语言·android studio
冷琅辞3 小时前
Elixir语言的云计算
开发语言·后端·golang
Mryan20054 小时前
解决GraalVM Native Maven Plugin错误:JAVA_HOME未指向GraalVM Distribution
java·开发语言·spring boot·maven
Naomi5214 小时前
自定义汇编语言(Custom Assembly Language) 和 Unix & Git
服务器·开发语言·git·unix
烂蜻蜓4 小时前
C 语言命令行参数:让程序交互更灵活
c语言·开发语言·交互
VX_CXsjNo14 小时前
免费送源码:Java+SSM+Android Studio 基于Android Studio游戏搜索app的设计与实现 计算机毕业设计原创定制
java·spring boot·spring·游戏·eclipse·android studio·android-studio
zm-v-159304339864 小时前
解锁 DeepSeek 与 Matlab:攻克科研难题的技术利刃
开发语言·matlab·信息可视化