Java并发编程(四):多线程带来的性能飞跃

Java并发编程(四):多线程带来的性能飞跃

编码文章call10242024-12-12 11:04:0435A+A-

多线程带来的性能飞跃

  • 1 概述
  • 2 程序示例及分析
    • 2.1 示例
    • 2.2 示例程序分析
  • 3 总结

大家好,我是欧阳方超,微信公众号同名。

1 概述

本文通过一个订单处理示例,演示一下使用多线程后可以带来显著的性能提升。

2 程序示例及分析

2.1 示例

模拟数据库库存

public class Inventory {
        //模拟数据库库存
        private final Object lock = new Object();
        private int stock = 1000;//初始库存1000

        public boolean deduct(int amount) {
            synchronized (lock) {
                if (stock >= amount) {
                    //模拟数据库延迟操作
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                    stock -= amount;
                    return true;
                }
                return false;
            }
        }

        public int getStock() {
            synchronized (lock) {
                return stock;
            }
        }
    }

模拟订单类

//订单类
class Order {
    private final int orderId;
    private final int quantity;
    private boolean isProcessed;

    public Order(int orderId, int quantity) {
        this.orderId = orderId;
        this.quantity = quantity;
        this.isProcessed = false;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setIsProcessed(boolean isProcessed) {
        this.isProcessed = isProcessed;
    }

    @Override
    public String toString() {
        return "Order{" +
                "orderId=" + orderId +
                ", quantity=" + quantity +
                ", isProcessed=" + isProcessed +
                '}';
    }
}

订单处理器
class OrderProcessor {
private final Inventory inventory;
private final AtomicInteger successCount = new AtomicInteger(0);
private final AtomicInteger failureCount = new AtomicInteger(0);

public OrderProcessor(Inventory inventory) {
    this.inventory = inventory;
}

public void process(Order order) {
    //模拟订单验证(无需加锁的耗时操作)
    validateOrder(order);

    //模拟订单价格计算(无需加锁的耗时操作)
    calculatePrice(order);

    //扣减库存(需要加锁的操作)
    boolean success = inventory.deduct(order.getQuantity());

    if (success) {
        //模拟发送确认操作邮件(无需加锁的耗时操作)
        sendConfirmationEmail(order);
        order.setIsProcessed(true);
        //order.isProcessed = true;
        successCount.incrementAndGet();
    } else {
        failureCount.incrementAndGet();
    }
}

public void validateOrder(Order order) {
    try {
        //模拟耗时的验证过程
        Thread.sleep(100);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public void calculatePrice(Order order) {
    try {
        //模拟耗时的价格计算
        Thread.sleep(100);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

private void sendConfirmationEmail(Order order) {
    try {
        //模拟耗时的发送邮件操作
        Thread.sleep(100);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();

    }
}

public int getSuccessCount() {
    return successCount.get();
}

public int getFailureCount() {
    return failureCount.get();
}

}

主方法所在类

public class OrderProcessingDemo {

    public static void main(String[] args) throws InterruptedException {
        //创建订单列表
        List<Order> orders = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 100; i++) {//创建100个订单
            //orders.add(new Order(i, random.nextInt(5) + 1));//每个订单购买1-5件商品
            orders.add(new Order(i, 5));//每个订单购买5件商品
        }
        Inventory inventory = new Inventory();
        OrderProcessor processor = new OrderProcessor(inventory);
        //单线程处理
        long startTime = System.currentTimeMillis();
        for (Order order : orders) {
            processor.process(order);
        }
        long singleThreadTime = System.currentTimeMillis() - startTime;

        //重置库存和处理器
        inventory = new Inventory();
        processor = new OrderProcessor(inventory);

        //多线程处理
        startTime = System.currentTimeMillis();
        ExecutorService executorService = Executors.newFixedThreadPool(20);
        List<CompletableFuture<Void>> futures = new ArrayList<>();
        for (Order order : orders) {
            OrderProcessor finalProcessor = processor;
            CompletableFuture<Void> future = CompletableFuture.runAsync(
                    () -> finalProcessor.process(order), executorService
            );
            futures.add(future);
        }

        //等待所有订单处理完成
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        executorService.shutdown();
        long multiThreadTime = System.currentTimeMillis() - startTime;


        // 打印结果
        System.out.println("单线程处理时间: " + singleThreadTime + "ms");
        System.out.println("多线程处理时间: " + multiThreadTime + "ms");
        System.out.println("性能提升: " + String.format("%.2f", (float) singleThreadTime / multiThreadTime) + "倍");
        System.out.println("成功处理订单数: " + processor.getSuccessCount());
        System.out.println("失败订单数: " + processor.getFailureCount());
        System.out.println("剩余库存: " + inventory.getStock());
    }

}

程序运行结果:

单线程处理时间: 34163ms
多线程处理时间: 2030ms
性能提升: 16.83倍
成功处理订单数: 100
失败订单数: 0
剩余库存: 500

2.2 示例程序分析

  1. Inventory类
    这个类模拟了一个库存管理系统。
    lock成员变量是用于同步库存操作的锁对象。
    dedect(int amount)方法尝试从库存中扣减指定数量的商品,使用synchronized关键词来确保线程安全。
  2. Order类
    这是一个订单类,没有太多与多线程相关的内容。
  3. OrderProcessor类
    这个类负责处理订单,并与库存进行交互。
  • 成员变量:inventory: 引用一个 Inventory 对象,用于库存管理。successCount 和 failureCount: 使用 AtomicInteger 来统计成功和失败的订单数,以保证在多线程环境下的线程安全。
  • 方法:process(Order order):验证订单(模拟耗时操作)。计算价格(模拟耗时操作)。尝试从库存中扣减请求的商品数量。如果成功,发送确认邮件并更新订单状态;如果失败,增加失败计数。validateOrder(Order order), calculatePrice(Order order), 和 sendConfirmationEmail(Order order):这些方法模拟了验证、价格计算和发送确认邮件的耗时操作。
  1. OrderProcessingDemo类
    这是程序的主类,负责执行整个订单处理流程。
  • main方法:创建一个包含100个订单的列表,每个订单有5件商品。创建一个Inventory对象和一个对应的OrderProcessor对象。单线程处理,使用单线程循环遍历所有订单并调用处理器进行处理,记录处理时间。多线程处理重置库存和处理器后,使用一个固定大小为20的线程池来并发处理所有订单。每个订单通过CompletableFuture.runAsync()方法异步处理,并将结果存储在一个列表中。使用CompletableFuture.allOf()等待所有异步任务完成,然后关闭线程池。输出结果
    最后程序打印单线程和多线程处理所需时间、性能提升倍数、成功和失败的订单数量以及剩余库存量。

3 总结

本文通过一个订单处理的示例,演示了使用多线程能够带来显著的性能飞跃。在实际项目中,通过将任务分解为多个并行执行的线程,能够更好地利用多核处理器的优势,提高系统并发处理能力。

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4