Java多线程优化接口响应

发布于:2024-05-07 ⋅ 阅读:(25) ⋅ 点赞:(0)

同步查询

 @Override
public MallOrder getById1(Long id) {
    long startTime = System.currentTimeMillis();

    MallOrder mallOrder = new MallOrder();
    mallOrder.setId(1L);
    mallOrder.setShopId(3L);
    mallOrder.setCustomerId(78L);
    mallOrder.setGoodsId(664L);
    mallOrder.setOrderTime(LocalDateTime.now());
    mallOrder.setOrderStatus(1);
    mallOrder.setTotalAmount(new BigDecimal("129.8"));

    // 商品
    Long goodsId = mallGoodsService.getById(mallOrder.getGoodsId());
    log.info("商品:" + goodsId);

    // 顾客
    Long customerId = mallCustomerService.getById(mallOrder.getCustomerId());
    log.info("顾客:" + customerId);


    // 店铺
    Long shopId = mallShopService.getById(mallOrder.getShopId());
    log.info("店铺:" + shopId);


    try {
        Thread.sleep(150);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

    long endTime = System.currentTimeMillis();
    log.info("耗时:" + (endTime - startTime));
    return mallOrder;
}
package com.qiangesoft.multithread.service.impl;

import com.qiangesoft.multithread.service.IMallShopService;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 店铺信息 服务实现类
 * </p>
 *
 * @author qiangesoft
 * @since 2024-05-06
 */
@Service
public class MallShopServiceImpl implements IMallShopService {

    @Override
    public Long getById(Long id) {
        try {
            Thread.sleep(350);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return id;
    }
}

package com.qiangesoft.multithread.service.impl;

import com.qiangesoft.multithread.service.IMallGoodsService;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 商品信息 服务实现类
 * </p>
 *
 * @author qiangesoft
 * @since 2024-05-06
 */
@Service
public class MallGoodsServiceImpl implements IMallGoodsService {

    @Override
    public Long getById(Long id) {
        try {
            Thread.sleep(280);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return id;
    }
}

package com.qiangesoft.multithread.service.impl;

import com.qiangesoft.multithread.service.IMallCustomerService;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 客户信息 服务实现类
 * </p>
 *
 * @author qiangesoft
 * @since 2024-05-06
 */
@Service
public class MallCustomerServiceImpl implements IMallCustomerService {

    @Override
    public Long getById(Long id) {
        try {
            Thread.sleep(230);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return id;
    }
}

在这里插入图片描述

异步优化

  • 核心线程数不变,仍旧是 cpu 数;
  • 最大线程数不变,仍旧是 cpu 数的5倍;
  • 空闲线程存活时间不变,仍旧是 5 分钟;
  • 使用 SynchronousQueue 替代 LinkedBlockingQueue(1024)。SynchronousQueue 是一个特殊的队列,其最大容量是1。也就是说,任何一次插入操作都必须等待一个相应的删除操作,反之亦然。如果没有相应的操作正在进行,则该线程将被阻塞;
  • 指定拒绝策略为 CallerRunsPolicy。当线程池资源不够时,由主线程来执行任务;

ps:在这个配置下,及时线程池中的所有资源全部耗尽,也只会降级到串行执行,不会让系统变的更糟糕。

private static int coreSize = Runtime.getRuntime().availableProcessors();

    private final ExecutorService executorService = new ThreadPoolExecutor(coreSize,
            coreSize * 5,
            5L,
            TimeUnit.MINUTES,
            // 最大容量为1的队列
            new SynchronousQueue<>(),
            // 拒绝策略,降级到主线程执行
            new ThreadPoolExecutor.CallerRunsPolicy());

    @Override
    public MallOrder getById(Long id) {
        long startTime = System.currentTimeMillis();

        MallOrder mallOrder = new MallOrder();
        mallOrder.setId(1L);
        mallOrder.setShopId(3L);
        mallOrder.setCustomerId(78L);
        mallOrder.setGoodsId(664L);
        mallOrder.setOrderTime(LocalDateTime.now());
        mallOrder.setOrderStatus(1);
        mallOrder.setTotalAmount(new BigDecimal("129.8"));

        // 商品
        Future<Long> goodsFuture = executorService.submit(() -> mallGoodsService.getById(mallOrder.getGoodsId()));

        // 顾客
        Future<Long> customerFuture = executorService.submit(() -> mallCustomerService.getById(mallOrder.getCustomerId()));

        // 店铺
        Future<Long> shopFuture = executorService.submit(() -> mallShopService.getById(mallOrder.getShopId()));

        try {
            Thread.sleep(150);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        try {
            log.info("商品:" + goodsFuture.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        try {
            log.info("顾客:" + customerFuture.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        try {
            log.info("店铺:" + shopFuture.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        long endTime = System.currentTimeMillis();
        log.info("耗时:" + (endTime - startTime));
        return mallOrder;
    }

在这里插入图片描述