[Java线程池之处理IO操作]

文章介绍了如何使用Java线程池处理IO操作以提高并发性能和响应速度,以及展示了使用Fork/Join框架处理CPU密集型任务的示例。通过线程池和CompletableFuture,可以更好地管理并发任务,而Fork/Join框架则能有效地分解和并行化计算任务。
摘要由CSDN通过智能技术生成

目录

 🥪前言:

 🥪下面是一个使用Java线程池处理IO操作的示例代码,可以提高并发性能和响应速度:

 🥪示例代码优化:

🥪依赖:

🥪java线程池处理CPU密集型任务

🥪下面是一个使用Fork/Join框架处理CPU密集型任务的示例代码:

 🥪实现逻辑:


 🥪前言:

   记录笔记

 🥪下面是一个使用Java线程池处理IO操作的示例代码,可以提高并发性能和响应速度:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class IOThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                executorService.submit(() -> {
                    // 处理每一行数据的逻辑
                    System.out.println(Thread.currentThread().getName() + ": " + line);
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        executorService.shutdown();
    }
}
  • 在上面的代码中,我们使用了Java线程池来处理读取文件的IO操作。我们使用了一个固定大小的线程池,可以同时处理10个任务。我们使用了try-with-resources语句来自动关闭文件流。在读取文件的每一行时,我们将其提交给线程池处理,从而提高程序的并发性能和响应速度。

 🥪示例代码优化:

  1. 使用线程池的预定义工厂方法:Java提供了一些预定义的线程池工厂方法,例如Executors.newFixedThreadPool()、Executors.newCachedThreadPool()、Executors.newSingleThreadExecutor()等。这些工厂方法可以根据不同的场景选择不同的线程池类型,从而提高程序的性能和可维护性。

  2. 使用线程池的拒绝策略:当线程池中的线程数量达到最大值时,新的任务将被拒绝。可以使用线程池的拒绝策略来处理这种情况,例如AbortPolicy、CallerRunsPolicy、DiscardPolicy、DiscardOldestPolicy等。这些策略可以根据不同的场景选择不同的处理方式,从而提高程序的可靠性和可维护性。

  3. 使用CompletableFuture来处理异步任务:Java 8引入了CompletableFuture类,可以方便地处理异步任务。可以使用CompletableFuture来替代线程池,从而提高程序的可读性和可维护性。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.*;

public class IOThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                CompletableFuture.runAsync(() -> {
                    // 处理每一行数据的逻辑
                    System.out.println(Thread.currentThread().getName() + ": " + line);
                }, executorService).exceptionally(e -> {
                    e.printStackTrace();
                    return null;
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        executorService.shutdown();
    }
}
  •  在上面的代码中,我们使用了Java 8的CompletableFuture类来处理异步任务。我们使用了线程池的预定义工厂方法来创建线程池。在处理每一行数据时,我们使用CompletableFuture.runAsync()方法来提交异步任务,并将其与线程池关联。我们还使用了CompletableFuture.exceptionally()方法来处理异常情况

🥪依赖:

上面的线程池示例代码没有使用任何第三方库,只使用了Java标准库中的类和接口,因此没有任何依赖。但是,如果您使用了Java 8的CompletableFuture类来处理异步任务,则需要Java 8及以上版本的JDK。

🥪java线程池处理CPU密集型任务

  • 对于CPU密集型任务,线程池并不能提高程序的并发性能,因为这种任务需要大量的CPU资源,而线程池中的线程数量是有限的。如果线程池中的线程数量小于CPU核心数,那么线程池并不能充分利用CPU资源,反而会增加线程切换的开销,降低程序的性能。
  • 对于CPU密集型任务,更好的做法是使用并行流或者Fork/Join框架来处理。这些框架可以将任务分解成多个子任务,并将子任务分配给多个线程执行,从而充分利用CPU资源,提高程序的并发性能。

🥪下面是一个使用Fork/Join框架处理CPU密集型任务的示例代码:

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class CPUThreadPoolDemo {
    public static void main(String[] args) {
        int[] data = new int[1000000];
        for (int i = 0; i < data.length; i++) {
            data[i] = i;
        }
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        long result = forkJoinPool.invoke(new SumTask(data, 0, data.length));
        System.out.println(result);
    }

    static class SumTask extends RecursiveTask<Long> {
        private static final int THRESHOLD = 10000;
        private int[] data;
        private int start;
        private int end;

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

        @Override
        protected Long compute() {
            if (end - start <= THRESHOLD) {
                long sum = 0;
                for (int i = start; i < end; i++) {
                    sum += data[i];
                }
                return sum;
            } else {
                int mid = (start + end) / 2;
                SumTask leftTask = new SumTask(data, start, mid);
                SumTask rightTask = new SumTask(data, mid, end);
                leftTask.fork();
                rightTask.fork();
                return leftTask.join() + rightTask.join();
            }
        }
    }
}
  • 在上面的代码中,我们使用了Fork/Join框架来处理CPU密集型任务。我们将任务分解成多个子任务,并将子任务分配给多个线程执行。在处理每个子任务时,我们使用了递归的方式来分解任务,直到任务的大小小于一个阈值。这种方式可以充分利用CPU资源,提高程序的并发性能。

 🥪实现逻辑:

  • main()方法:在主线程中创建一个ForkJoinPool对象,并将任务提交给该线程池处理。在处理完任务后,输出任务的结果。

  • SumTask类:继承自RecursiveTask类,用于计算数组中所有元素的和。如果任务的大小小于一个阈值,则直接计算任务的结果;否则,将任务分解成两个子任务,并将子任务分配给不同的线程执行。在处理完子任务后,将子任务的结果合并起来,得到任务的结果。

  • compute()方法:重写了RecursiveTask类的compute()方法,用于计算任务的结果。如果任务的大小小于一个阈值,则直接计算任务的结果;否则,将任务分解成两个子任务,并将子任务分配给不同的线程执行。在处理完子任务后,将子任务的结果合并起来,得到任务的结果。

  • THRESHOLD常量:用于指定任务的大小阈值。如果任务的大小小于该阈值,则直接计算任务的结果;否则,将任务分解成两个子任务,并将子任务分配给不同的线程执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是汤圆丫

怎么 给1分?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值