• 学习分享-FutureTask和消息队列的区别


    前言

    上篇回顾了一下FutureTask 的相关原理,现在分享一下它和消息队列的区别。

    FutureTask 和消息队列的区别

    FutureTask 和消息队列都是用于处理并发任务的工具,但它们的应用场景和功能有很大的不同。以下是两者之间的主要区别:

    1. 定义与用途
    • FutureTask

      • 定义FutureTask 是一个实现了 RunnableFuture 接口的类,用于封装异步任务,并且能够获取任务的执行结果。
      • 用途:用于管理单个任务的异步执行,可以在任务完成后获取结果或取消任务,适合处理需要返回结果的任务。
    • 消息队列

      • 定义:消息队列是一种用于在分布式系统中传递消息的数据结构,通常用于解耦生产者和消费者。
      • 用途:用于在不同系统或不同模块之间传递消息,适合处理异步通信、大规模并发请求、任务队列、事件驱动架构等场景。
    2. 工作原理
    • FutureTask

      • 任务被封装为一个 CallableRunnable 对象,并由 FutureTask 执行。
      • 通过 ExecutorService 提交 FutureTask,任务会被线程池中的线程执行。
      • 可以通过 FutureTaskget() 方法获取任务执行结果,或者通过 cancel() 方法取消任务。
    • 消息队列

      • 生产者(Producer)将消息放入队列。
      • 消息队列中介存储消息,并按照一定的顺序分发给消费者(Consumer)。
      • 消费者从队列中读取消息并处理,生产者和消费者是解耦的,可以独立扩展和维护。
    3. 适用场景
    • FutureTask

      • 需要执行异步任务,并且需要获取任务执行结果。
      • 适用于单一任务的管理,如并发计算、异步 I/O 操作等。
    • 消息队列

      • 系统之间需要解耦,或者需要缓冲高峰期的流量。
      • 适用于异步通信、任务调度、事件驱动系统、分布式系统中的数据传递等场景。
    4. 异步处理方式
    • FutureTask

      • 由线程池管理任务执行,任务完成后可以获取结果或取消任务。
      • 主要用于并发编程中的任务管理。
    • 消息队列

      • 生产者异步发送消息,消费者异步接收消息,双方解耦。
      • 主要用于系统间的异步通信和任务调度。

    示例代码

    FutureTask 示例
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.FutureTask;
    
    public class FutureTaskExample {
    
        public static void main(String[] args) {
            Callable<String> callableTask = () -> {
                Thread.sleep(2000);
                return "Task completed";
            };
    
            FutureTask<String> futureTask = new FutureTask<>(callableTask);
            ExecutorService executorService = Executors.newSingleThreadExecutor();
            executorService.submit(futureTask);
    
            System.out.println("Main thread is doing other work...");
    
            try {
                String result = futureTask.get();
                System.out.println("FutureTask result: " + result);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
    
            executorService.shutdown();
        }
    }
    
    消息队列示例(使用 RabbitMQ)
    import com.rabbitmq.client.Channel;
    import com.rabbitmq.client.Connection;
    import com.rabbitmq.client.ConnectionFactory;
    
    public class RabbitMQExample {
    
        private final static String QUEUE_NAME = "hello";
    
        public static void main(String[] args) throws Exception {
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            try (Connection connection = factory.newConnection();
                 Channel channel = connection.createChannel()) {
                channel.queueDeclare(QUEUE_NAME, false, false, false, null);
                String message = "Hello World!";
                channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
                System.out.println(" [x] Sent '" + message + "'");
            }
        }
    }
    

    总结

    • FutureTask 适用于管理单个异步任务,提供获取结果和取消任务的能力,主要用于并发编程。
    • 消息队列 适用于系统间的异步通信和任务调度,解耦生产者和消费者,适合分布式系统和大规模并发场景。

    这两者各自有其独特的应用场景和优势,根据具体需求选择合适的工具。

  • 相关阅读:
    Git 常用命令
    【论文阅读】VulCNN受图像启发的可扩展漏洞检测系统
    Redis—听说你速度跟甲斗一样快?——cluster
    RabbitMQ 怎么保证可靠性、幂等性、消费顺序?
    人工智能、深度学习、机器学习常见面试题261~280
    漫谈:C语言 C++ static究竟是什么
    剑指offer(C++)-JZ67:把字符串转换成整数atoi(算法-模拟)
    【java】【SSM框架系列】【四】SpringBoot
    家用电器行业商业供应链协同平台解决方案:供应链系统管理精益化,助推企业智造升级
    Android (微信扫码登录) 获取微信二维码+扫码登录
  • 原文地址:https://blog.csdn.net/weixin_62079735/article/details/139664264