同步查询
@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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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());@Overridepublic 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;}