主页 > 电脑硬件  > 

多线程学习之路

多线程学习之路

多线程的创建方式主要有以下几种:

1. 继承 Thread 类

通过继承 Thread 类并重写 run() 方法来创建线程。

class MyThread extends Thread { @Override public void run() { // 线程执行的任务 System.out.println("Thread is running"); } } public class Main { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); // 启动线程 } } 2. 实现 Runnable 接口

通过实现 Runnable 接口并实现 run() 方法,然后将 Runnable 对象传递给 Thread 类的构造函数。

class MyRunnable implements Runnable { @Override public void run() { // 线程执行的任务 System.out.println("Thread is running"); } } public class Main { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); // 启动线程 } } 3. 实现 Callable 接口

通过实现 Callable 接口并实现 call() 方法,Callable 可以返回结果并抛出异常。通常与 ExecutorService 一起使用。

import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; class MyCallable implements Callable<String> { @Override public String call() throws Exception { // 线程执行的任务 return "Thread is running"; } } public class Main { public static void main(String[] args) { ExecutorService executor = Executors.newSingleThreadExecutor(); MyCallable myCallable = new MyCallable(); Future<String> future = executor.submit(myCallable); try { String result = future.get(); // 获取线程执行结果 System.out.println(result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } finally { executor.shutdown(); } } } 4. 使用线程池

通过 ExecutorService 和 Executors 工具类创建线程池,提交任务给线程池执行。

import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Main { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(5); for (int i = 0; i < 10; i++) { Runnable task = new MyRunnable(); executor.execute(task); } executor.shutdown(); } } 5. 使用 CompletableFuture(Java 8+)

CompletableFuture 提供了更高级的异步编程方式,支持链式调用和组合多个异步任务。

import java.util.concurrent.CompletableFuture; public class Main { public static void main(String[] args) { CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { // 异步执行的任务 System.out.println("Thread is running"); }); future.join(); // 等待任务完成 } } 6. 使用 Timer 和 TimerTask

Timer 和 TimerTask 可以用于创建定时任务,TimerTask 实现了 Runnable 接口。

import java.util.Timer; import java.util.TimerTask; public class Main { public static void main(String[] args) { Timer timer = new Timer(); TimerTask task = new TimerTask() { @Override public void run() { // 定时执行的任务 System.out.println("Thread is running"); } }; timer.schedule(task, 0, 1000); // 延迟0毫秒,每隔1000毫秒执行一次 } } 7. 使用 ForkJoinPool(Java 7+)

ForkJoinPool 是用于并行执行任务的线程池,特别适合分治算法和递归任务。

import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveAction; class MyRecursiveAction extends RecursiveAction { @Override protected void compute() { // 并行执行的任务 System.out.println("Thread is running"); } } public class Main { public static void main(String[] args) { ForkJoinPool pool = new ForkJoinPool(); MyRecursiveAction task = new MyRecursiveAction(); pool.invoke(task); } } 8.list.parallelStream()

import java.util.Arrays; import java.util.List;

public class ParallelStream { public static void main(String[] args) { List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10); list.parallelStream().forEach(System.out::println); } }

parallelStream 是基于 Fork/Join 框架 实现的,它允许将任务拆分成多个子任务并行处理,最后将结果合并。以下是 parallelStream 的底层实现原理:

Fork/Join 框架 parallelStream 的并行处理依赖于 Java 7 引入的 Fork/Join 框架。该框架的核心思想是: 分治(Divide and Conquer):将一个大任务拆分成多个小任务(Fork),并行执行这些小任务,最后将结果合并(Join)。 工作窃取(Work Stealing):每个线程维护一个任务队列,当某个线程完成任务后,可以从其他线程的队列中“窃取”任务来执行,从而提高 CPU 利用率。并行流的执行流程 当调用 parallelStream() 时,Java 会创建一个并行流,其底层执行流程如下: (1) 任务拆分 数据源(如集合)会被拆分成多个子任务。 拆分的方式取决于数据源的类型: 对于 ArrayList 等可拆分的数据结构,会按照索引范围拆分成多个子任务。 对于 HashSet 等不可直接拆分的数据结构,会先转换为数组再进行拆分。 (2) 并行执行 每个子任务会被提交到 Fork/Join 线程池(ForkJoinPool monPool())中执行。 默认情况下,线程池的大小为 CPU 核心数 - 1(可以通过 -Djava.util.concurrent.ForkJoinPool mon.parallelism 参数调整)。 (3) 结果合并 每个子任务执行完成后,结果会被合并(Join)。 合并的方式取决于流的操作类型(如 reduce、collect 等)。并行流的性能优化 数据量:并行流适合处理大规模数据,小数据量时串行流(stream())可能更快,因为并行化会引入额外的开销(如任务拆分、线程调度等)。 数据结构:数据源的结构影响拆分效率。ArrayList 和数组等支持随机访问的数据结构更适合并行流,而 LinkedList 等链表结构则不适合。 操作类型:某些操作(如 filter、map)适合并行化,而某些操作(如 limit、findFirst)可能会限制并行化的效果。 总结

继承 Thread 类:简单直接,但Java不支持多继承,灵活性较差。

实现 Runnable 接口:更灵活,推荐使用。

实现 Callable 接口:可以返回结果和抛出异常,适合需要返回值的场景。

线程池:高效管理线程资源,适合大量异步任务。

CompletableFuture:支持复杂的异步编程。

Timer 和 TimerTask:适合定时任务。

ForkJoinPool:适合并行计算和分治任务。

根据具体需求选择合适的方式。

标签:

多线程学习之路由讯客互联电脑硬件栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“多线程学习之路