首页 > 编程语言 >java同时处理多个数据

java同时处理多个数据

时间:2024-05-22 10:55:20浏览次数:18  
标签:java 多个 处理 number 列表 int Future 线程 CompletableFuture

在Java中,同时处理多个数据通常涉及多线程、并发编程或异步编程。这里我将提供一个使用多线程的示例,因为多线程是处理多个数据并行的常见方式。

首先,我们需要定义一个任务(例如,处理一个数据项),然后创建多个线程来并行执行这些任务。

1.使用多线程处理多个数据

假设我们有一个整数列表,并且我们想要并行地对列表中的每个整数执行某个操作(例如,计算平方)。

(1)定义任务:我们可以创建一个实现Runnable接口的类来表示任务。

(2)创建线程:对于列表中的每个数据项,我们创建一个新的线程来执行该任务。

(3)启动线程:调用线程的start()方法来启动线程。

(4)等待线程完成:如果需要,我们可以使用join()方法来等待所有线程完成。

下面是完整的代码示例:

import java.util.ArrayList;  
import java.util.List;  
  
public class MultiDataProcessingExample {  
  
    // 定义任务:计算整数的平方  
    static class SquareTask implements Runnable {  
        private int number;  
  
        public SquareTask(int number) {  
            this.number = number;  
        }  
  
        @Override  
        public void run() {  
            int square = number * number;  
            System.out.println("The square of " + number + " is " + square);  
        }  
    }  
  
    public static void main(String[] args) {  
        // 创建一个整数列表  
        List<Integer> numbers = new ArrayList<>();  
        for (int i = 1; i <= 10; i++) {  
            numbers.add(i);  
        }  
  
        // 为每个整数创建一个线程来计算平方  
        List<Thread> threads = new ArrayList<>();  
        for (int number : numbers) {  
            Thread thread = new Thread(new SquareTask(number));  
            threads.add(thread);  
            thread.start(); // 启动线程  
        }  
  
        // 等待所有线程完成(可选)  
        for (Thread thread : threads) {  
            try {  
                thread.join();  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
  
        // 所有线程都已完成,继续主线程的其他操作(如果有的话)  
        System.out.println("All threads have finished.");  
    }  
}

在这个示例中,我们定义了一个SquareTask类来实现Runnable接口,该类表示计算整数平方的任务。然后,在main方法中,我们创建了一个包含1到10的整数的列表,并为列表中的每个整数创建了一个新的线程来执行SquareTask。最后,我们启动了所有线程,并(可选地)等待它们完成。

2.使用JavaExecutorServiceCallable接口来处理多个数据示例

下面是一个使用Java的ExecutorServiceCallable接口来处理多个数据的示例。在这个例子中,我们将使用ExecutorService来管理线程池,并使用Future来获取每个任务的结果。

首先,我们定义一个实现Callable接口的任务,它返回计算后的结果。然后,我们创建一个ExecutorService,提交多个任务,并使用Future对象来收集结果。

import java.util.ArrayList;  
import java.util.List;  
import java.util.concurrent.*;  
  
public class MultiDataProcessingWithExecutorService {  
  
    // 定义任务:计算整数的平方并返回结果  
    static class SquareCallable implements Callable<Integer> {  
        private final int number;  
  
        public SquareCallable(int number) {  
            this.number = number;  
        }  
  
        @Override  
        public Integer call() throws Exception {  
            int square = number * number;  
            return square;  
        }  
    }  
  
    public static void main(String[] args) throws ExecutionException, InterruptedException {  
        // 创建一个整数列表  
        List<Integer> numbers = new ArrayList<>();  
        for (int i = 1; i <= 10; i++) {  
            numbers.add(i);  
        }  
  
        // 创建一个固定大小的线程池  
        ExecutorService executorService = Executors.newFixedThreadPool(5);  
  
        // 提交任务并获取Future列表  
        List<Future<Integer>> futures = new ArrayList<>();  
        for (int number : numbers) {  
            Future<Integer> future = executorService.submit(new SquareCallable(number));  
            futures.add(future);  
        }  
  
        // 获取并打印每个任务的结果  
        for (Future<Integer> future : futures) {  
            // 注意:get()方法会阻塞,直到任务完成  
            Integer result = future.get();  
            System.out.println("The square of " + (futures.indexOf(future) + 1) + " is " + result);  
        }  
  
        // 关闭线程池  
        executorService.shutdown();  
  
        // 等待所有任务完成(如果还没有完成的话)  
        try {  
            // 等待线程池中的任务在指定的时间内完成  
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {  
                // 线程池没有在给定的时间内终止,我们可以选择取消它  
                executorService.shutdownNow();  
            }  
        } catch (InterruptedException ie) {  
            // 当前线程在等待过程中被中断  
            executorService.shutdownNow();  
            Thread.currentThread().interrupt();  
        }  
  
        // 所有线程都已完成,继续主线程的其他操作(如果有的话)  
        System.out.println("All threads have finished.");  
    }  
}

在这个示例中,我们使用Executors.newFixedThreadPool(5)创建了一个包含5个线程的线程池。然后,我们为列表中的每个整数提交了一个SquareCallable任务,并将返回的Future对象保存在列表中。通过调用future.get()方法,我们可以获取每个任务的结果,并打印出来。最后,我们关闭了线程池,并等待所有任务完成。

使用ExecutorServiceCallable通常比直接使用ThreadRunnable更加方便和灵活,因为ExecutorService提供了对线程池的管理,而Callable允许任务返回结果。

3.使用并发编程同时处理多个数据

在Java并发编程中,一种常见的方法是使用ExecutorServiceCallable接口来同时处理多个数据,并收集结果。以下是一个完整的代码示例,展示了如何使用ExecutorServiceFuture来同时处理一个整数列表中的每个元素,并收集它们的平方结果:

import java.util.ArrayList;  
import java.util.List;  
import java.util.concurrent.*;  
  
public class ConcurrentSquareCalculator {  
  
    // 定义一个Callable任务来计算平方  
    static class SquareCallable implements Callable<Integer> {  
        private final int number;  
  
        public SquareCallable(int number) {  
            this.number = number;  
        }  
  
        @Override  
        public Integer call() throws Exception {  
            return number * number;  
        }  
    }  
  
    public static void main(String[] args) throws ExecutionException, InterruptedException {  
        // 创建一个整数列表  
        List<Integer> numbers = new ArrayList<>();  
        for (int i = 1; i <= 10; i++) {  
            numbers.add(i);  
        }  
  
        // 创建一个固定大小的线程池  
        ExecutorService executorService = Executors.newFixedThreadPool(5);  
  
        // 提交任务并收集Future对象  
        List<Future<Integer>> futures = new ArrayList<>();  
        for (int number : numbers) {  
            Future<Integer> future = executorService.submit(new SquareCallable(number));  
            futures.add(future);  
        }  
  
        // 等待所有任务完成并收集结果  
        List<Integer> squares = new ArrayList<>();  
        for (Future<Integer> future : futures) {  
            // 注意:get()方法会阻塞,直到任务完成  
            Integer square = future.get();  
            squares.add(square);  
        }  
  
        // 打印结果  
        for (int i = 0; i < numbers.size(); i++) {  
            System.out.println("The square of " + numbers.get(i) + " is " + squares.get(i));  
        }  
  
        // 关闭线程池  
        executorService.shutdown();  
  
        // 等待线程池中的任务都执行完毕  
        try {  
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {  
                // 线程池没有在给定的时间内终止,可以选择取消它  
                executorService.shutdownNow();  
            }  
        } catch (InterruptedException ie) {  
            // 当前线程在等待过程中被中断  
            executorService.shutdownNow();  
            Thread.currentThread().interrupt();  
        }  
  
        // 所有线程都已完成,继续主线程的其他操作(如果有的话)  
        System.out.println("All threads have finished.");  
    }  
}

在这个示例中,我们创建了一个SquareCallable类,它实现了Callable<Integer>接口,用于计算一个整数的平方。然后,在main方法中,我们创建了一个包含1到10的整数的列表,并创建了一个大小为5的固定线程池。

接下来,我们遍历整数列表,为每个整数创建一个SquareCallable任务,并提交给线程池执行。线程池会管理这些任务的执行,并返回Future对象,这些对象可以用于获取任务的结果。

我们将这些Future对象收集到一个列表中,并遍历这个列表,使用get()方法来获取每个任务的结果,并将结果收集到另一个列表中。注意,get()方法会阻塞,直到任务完成并返回结果。

最后,我们打印出每个原始数字的平方结果,并关闭线程池。我们还使用awaitTermination方法来等待线程池中的所有任务都执行完毕,以确保所有资源都被正确释放。

4.使用异步编程同时处理多个数据

在Java中进行异步编程以同时处理多个数据的一种常见方式是使用CompletableFutureCompletableFuture是Java 8中引入的一个功能强大的类,它代表了一个异步计算的结果。以下是一个使用CompletableFuture来同时处理多个数据的示例:

import java.util.ArrayList;  
import java.util.List;  
import java.util.concurrent.CompletableFuture;  
import java.util.concurrent.ExecutionException;  
import java.util.stream.Collectors;  
  
public class AsyncProcessingExample {  
  
    // 一个方法用于模拟计算平方  
    public static int square(int number) {  
        // 假设这里有一些计算  
        try {  
            // 模拟耗时操作  
            Thread.sleep(1000);  
        } catch (InterruptedException e) {  
            Thread.currentThread().interrupt();  
        }  
        return number * number;  
    }  
  
    public static void main(String[] args) throws ExecutionException, InterruptedException {  
        // 创建一个整数列表  
        List<Integer> numbers = List.of(1, 2, 3, 4, 5);  
  
        // 使用stream和CompletableFuture.supplyAsync来异步处理每个数字  
        List<CompletableFuture<Integer>> futures = numbers.stream()  
                .map(number -> CompletableFuture.supplyAsync(() -> square(number)))  
                .collect(Collectors.toList());  
  
        // 使用CompletableFuture.allOf等待所有Future完成  
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));  
  
        // 等待所有任务完成  
        allFutures.join();  
  
        // 收集结果  
        List<Integer> squares = futures.stream()  
                .map(future -> {  
                    try {  
                        return future.get(); // 这可能会抛出异常,但在这个例子中我们假设没有异常  
                    } catch (InterruptedException | ExecutionException e) {  
                        throw new IllegalStateException(e);  
                    }  
                })  
                .collect(Collectors.toList());  
  
        // 打印结果  
        squares.forEach(System.out::println);  
    }  
}

在这个示例中,我们首先创建了一个包含整数的列表。然后,我们使用Java 8的流(Stream)API和CompletableFuture.supplyAsync来异步处理列表中的每个数字。supplyAsync方法会返回一个CompletableFuture,它代表异步计算的结果。

我们收集所有的CompletableFuture到一个列表中,并使用CompletableFuture.allOf来等待所有的Future完成。allOf方法返回一个新的CompletableFuture<Void>,当所有给定的Future都完成时,这个新的Future就完成了。

然后,我们调用join()方法来等待所有的Future完成。join()方法会阻塞当前线程,直到Future完成。

最后,我们再次使用流来从每个CompletableFuture中获取结果,并将它们收集到一个新的列表中。我们使用get()方法来获取结果,但请注意,如果Future的计算抛出异常,get()方法也会抛出异常。在这个例子中,我们假设没有异常,但在实际应用中,你应该妥善处理这些异常。

最后,我们打印出计算得到的平方数。

标签:java,多个,处理,number,列表,int,Future,线程,CompletableFuture
From: https://www.cnblogs.com/TS86/p/18205735

相关文章

  • Java核心面试知识集—Kafka面试题
    目录基础篇1、TCP、UDP的区别?2、TCP协议如何保证可靠传输?3、TCP的握手、挥手机制?4、TCP的粘包/拆包原因及其解决方法是什么?5、Netty的粘包/拆包是怎么处理的,有哪些实现?6、同步与异步、阻塞与非阻塞的区别?7、说说网络IO模型?8、BIO、NIO、AIO分别是什么?9、select、poll、epoll的机制......
  • java面试题
    面向对象的基本特征?分别什么含义封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。多态:多态性是指允许不同类的对象对同一消息作出响应。重载和重写的区别?重载:在......
  • Java核心面试知识集—设计模式
    设计模式知识点笔记汇总1.单例模式(SingletonPattern)2.工厂模式3.抽象工厂模式(AbstractFactoryPattern)4.模板方法模式(TemplateMethodPattern)5.建造者模式(BuilderPattern)6.代理模式(ProxyPattern)7.原型模式(PrototypePattern)8.中介者模式9.命令模式10.责任链模式11......
  • Java核心面试知识集—计算机网络基础
    计算机网络体系结构在计算机网络的基本概念中,分层次的体系结构是最基本的。计算机网络体系结构的抽象概念较多,在学习时要多思考。这些概念对后面的学习很有帮助。网络协议是什么?在计算机网络要做到有条不紊地交换数据,就必须遵守一些事先约定好的规则,比如交换数据的格式、是否需......
  • Java核心面试知识集—大厂数据库面试题
    事务四大特性(ACID)原子性、一致性、隔离性、持久性?原子性(Atomicity)原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。一致性(Consistency)事务开始前和结束后,数据库的完整性......
  • Java核心面试知识集—常见面试算法题
    排序比较排序冒泡排序重复地走访过要排序的数列,每次比较相邻两个元素,如果它们的顺序错误就把它们交换过来,越大的元素会经由交换慢慢“浮”到数列的尾端。publicvoidbubbleSort(int[]arr){inttemp=0;booleanswap;for(inti=arr.length-1;i>0;i......
  • Java核心面试知识集—zookeeper面试题
    1.ZooKeeper是什么?ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。客户端的读请求可......
  • Java核心面试知识集—Tomcat面试题
    Tomcat是什么?Tomcat服务器Apache软件基金会项目中的一个核心项目,是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选。Tomcat的缺省端口是多少,怎么修改找到Tomcat目录下的conf文件......
  • Java核心面试知识集—Spring面试题
    Spring概述(10)什么是spring?Spring是一个轻量级Java开发框架,最早有RodJohnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEEfull-stack(一站式)轻量级开源框架,为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,......
  • Java核心面试知识集—SpringMVC面试题
    概述什么是SpringMVC?简单介绍下你对SpringMVC的理解?SpringMVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把模型-视图-控制器分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。SpringMVC......