高并发下的批量处理与单个处理(利用jdk8新特性处理,提高性能)

1、技术选型:

SpringBoot

2、案例:

实体类:

package com.zhangwl.complicatedemo.pojo;

import java.sql.Timestamp;

/** * @ClassName Goods * @Description * @Author zhangwl * @Date 2019/10/3 0:54 * @Version 1.0 **/public class Goods {

    private String goodsName;    private Timestamp goodsDate;    private String goodsCode;    private String serialNumber;

    public Goods() {    }

    public Goods(String goodsName, Timestamp goodsDate, String goodsCode, String serialNumber) {        this.goodsName = goodsName;        this.goodsDate = goodsDate;        this.goodsCode = goodsCode;        this.serialNumber = serialNumber;    }

    public String getGoodsName() {        return goodsName;    }

    public void setGoodsName(String goodsName) {        this.goodsName = goodsName;    }

    public Timestamp getGoodsDate() {        return goodsDate;    }

    public void setGoodsDate(Timestamp goodsDate) {        this.goodsDate = goodsDate;    }

    public String getGoodsCode() {        return goodsCode;    }

    public void setGoodsCode(String goodsCode) {        this.goodsCode = goodsCode;    }

    public String getSerialNumber() {        return serialNumber;    }

    public void setSerialNumber(String serialNumber) {        this.serialNumber = serialNumber;    }

    @Override    public String toString() {        return "Goods{" +                "goodsName=‘" + goodsName + ‘\‘‘ +                ", goodsDate=" + goodsDate +                ", goodsCode=‘" + goodsCode + ‘\‘‘ +                ", serialNumber=‘" + serialNumber + ‘\‘‘ +                ‘}‘;    }}
package com.zhangwl.complicatedemo.pojo;

import java.util.Map;import java.util.concurrent.CompletableFuture;

/** * @ClassName Request * @Description 封装请求的实体,达到批量求的目的 * @Author zhangwl * @Date 2019/10/5 17:22 * @Version 1.0 **/public class Request {

    private String goodsCode;

    CompletableFuture<Map<String, Object>> future = null;

    public Request() {    }

    public Request(String goodsCode, CompletableFuture<Map<String, Object>> future) {        this.goodsCode = goodsCode;        this.future = future;    }

    public CompletableFuture<Map<String, Object>> getFuture() {        return future;    }

    public void setFuture(CompletableFuture<Map<String, Object>> future) {        this.future = future;    }

    public String getGoodsCode() {        return goodsCode;    }

    public void setGoodsCode(String goodsCode) {        this.goodsCode = goodsCode;    }

    @Override    public String toString() {        return "Request{" +                "goodsCode=‘" + goodsCode + ‘\‘‘ +                ‘}‘;    }}******************************************************************************************************************************************业务层:
package com.zhangwl.complicatedemo.service;

import com.zhangwl.complicatedemo.pojo.Goods;

import java.util.Map;import java.util.concurrent.ExecutionException;

/** * @ClassName GoodsService * @Description * @Author zhangwl * @Date 2019/10/3 0:52 * @Version 1.0 **/public interface GoodsService {

    Map<String, Goods> findGoodsByGoodsCode(String goodsCode);

    Map<String ,Object> getGoodsByGoodsCode(String goodsCode) throws ExecutionException, InterruptedException;}
package com.zhangwl.complicatedemo.service;

import com.zhangwl.complicatedemo.pojo.Goods;import org.springframework.stereotype.Service;

import java.util.List;import java.util.Map;

/** * @ClassName RemoteGoodsServiceCall * @Description 远程调用接口 * @Author zhangwl * @Date 2019/10/6 11:33 * @Version 1.0 **/public interface RemoteGoodsService {

    Map<String, Goods> findGoodsByGoodsCode(String goodsCode);

    List<Map<String, Object>> findGoodsByBatchGoodsCode(List<String> goodsCodes);}
package com.zhangwl.complicatedemo.service.impl;

import com.zhangwl.complicatedemo.pojo.Goods;import com.zhangwl.complicatedemo.pojo.Request;import com.zhangwl.complicatedemo.service.GoodsService;import com.zhangwl.complicatedemo.service.RemoteGoodsService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;import java.util.*;import java.util.concurrent.*;

/** * @ClassName GoodsServiceImpl * @Description * @Author zhangwl * @Date 2019/10/3 0:52 * @Version 1.0 **/@Servicepublic class GoodsServiceImpl implements GoodsService {

    @Autowired    private RemoteGoodsService remoteGoodsService;

    private LinkedBlockingQueue<Request> linkedBlockingQueue = new LinkedBlockingQueue<>();

    @Override    public Map<String, Goods> findGoodsByGoodsCode(String goodsCode) {        Map<String, Goods> map = remoteGoodsService.findGoodsByGoodsCode(goodsCode);        return map;    }

    @Override    public Map<String, Object> getGoodsByGoodsCode(String goodsCode) throws ExecutionException, InterruptedException {        /*jdk8将请求结果一一映射(通知)到线程*/        CompletableFuture<Map<String, Object>> future = new CompletableFuture<Map<String, Object>>();        Request request = new Request(goodsCode, future);        linkedBlockingQueue.add(request);        /*一直阻塞等待,有结果则返回结果*/        return future.get();    }

    @PostConstruct    public void init() {        /*创建一个定时器*/        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);        scheduledExecutorService.scheduleAtFixedRate(() -> {            int size = linkedBlockingQueue.size();            if (size == 0) {                return;            }            List<Request> requests = new LinkedList<>();            /*说明队列中有数据*/            linkedBlockingQueue.forEach(o -> {                /*从队列中获取数据*/                Request request = linkedBlockingQueue.poll();                requests.add(request);            });

            List<String> params = new LinkedList<>();            /*批量处理调用接口*/            requests.forEach(o -> {                params.add(o.getGoodsCode());            });            List<Map<String, Object>> goodsMapList = remoteGoodsService.findGoodsByBatchGoodsCode(params);            Map<String, Map<String, Object>> mapResult = new HashMap<>();            goodsMapList.forEach(o -> {                Set<String> keys = o.keySet();                keys.forEach(o1 ->mapResult.put(o1,o));            });            requests.forEach(o -> {                Map<String, Object> result = mapResult.get(o.getGoodsCode());                o.getFuture().complete(result);            });        }, 0, 10, TimeUnit.MILLISECONDS);    }

}

package com.zhangwl.complicatedemo.service.impl;

import com.zhangwl.complicatedemo.pojo.Goods;import com.zhangwl.complicatedemo.service.RemoteGoodsService;import com.zhangwl.complicatedemo.utils.CommonUtils;import org.springframework.stereotype.Service;

import java.sql.Timestamp;import java.time.Instant;import java.util.HashMap;import java.util.LinkedList;import java.util.List;import java.util.Map;

/** * @ClassName RemoteGoodsServiceCallImpl * @Description * @Author zhangwl * @Date 2019/10/6 11:34 * @Version 1.0 **/@Servicepublic class RemoteGoodsServiceImpl implements RemoteGoodsService {    @Override    public Map<String, Goods> findGoodsByGoodsCode(String goodsCode) {        String uuid = CommonUtils.getUUIDString();        Goods goods = new Goods();        long mills = System.currentTimeMillis();        goods.setGoodsName("name" + mills + uuid.substring(0, 3));        goods.setGoodsDate(Timestamp.from(Instant.now()));        goods.setSerialNumber(uuid);        Map<String, Goods> map = new HashMap<>();        map.put(goodsCode, goods);        return map;    }

    @Override    public List<Map<String, Object>> findGoodsByBatchGoodsCode(List<String> goodsCodes) {        List<Map<String, Object>> resultList = new LinkedList<>();        goodsCodes.forEach(o -> {            String uuid = CommonUtils.getUUIDString();            Goods goods = new Goods();            long mills = System.currentTimeMillis();            goods.setGoodsName("name" + mills + uuid.substring(0, 3));            goods.setGoodsDate(Timestamp.from(Instant.now()));            goods.setGoodsCode(o);            goods.setSerialNumber(uuid);            Map<String, Object> map = new HashMap<>();            map.put(o, goods);            resultList.add(map);        });        return resultList;    }}
******************************************************************************************************************************************测试类:
package com.zhangwl.complicatedemo;

import com.alibaba.fastjson.JSON;import com.zhangwl.complicatedemo.pojo.Goods;import com.zhangwl.complicatedemo.service.GoodsService;import com.zhangwl.complicatedemo.utils.CommonUtils;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;

import java.util.Map;import java.util.Set;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutionException;

@RunWith(SpringRunner.class)@SpringBootTestpublic class ComplicatedemoApplicationTests {

    private static final int T_NUM = 10000;

    /*同步计数器*/    private CountDownLatch countDownLatch1 = new CountDownLatch(T_NUM);    private CountDownLatch countDownLatch2 = new CountDownLatch(T_NUM);

    @Autowired    private GoodsService goodsService;

    @Test    public void contextLoads_01() throws InterruptedException {        for (int i = 0; i < T_NUM; i++) {            Thread t = new Thread(() -> {                try {                    countDownLatch1.await();                    Map<String, Goods> goodsMap = goodsService.findGoodsByGoodsCode(CommonUtils.getUUIDString());                    Set<String> keys = goodsMap.keySet();                    keys.forEach(o -> {                        String goodsJson = JSON.toJSONString(goodsMap.get(o));                        System.out.println(goodsJson);                    });                } catch (InterruptedException e) {                    e.printStackTrace();                }            });            t.start();            countDownLatch1.countDown();        }

        Thread.sleep(3000);    }

    /*    * 利用jdk8提高并发处理的能力    */    @Test    public void contextLoads_02() throws InterruptedException {        for (int i = 0; i < T_NUM; i++) {            Thread t = new Thread(() -> {                try {                    countDownLatch2.await();                    Map<String, Object> goodsMap = goodsService.getGoodsByGoodsCode(CommonUtils.getUUIDString());                    Set<String> keys = goodsMap.keySet();                    keys.forEach(o -> {                        String goodsJson = JSON.toJSONString(goodsMap.get(o));                        System.out.println(goodsJson);                    });                } catch (InterruptedException e) {                    e.printStackTrace();                } catch (ExecutionException e) {                    e.printStackTrace();                }            });            t.start();            countDownLatch2.countDown();        }

        Thread.sleep(2000);    }

}

运行结果:测试类中,
contextLoads_02测试方法的性能优于contextLoads_01方法。


原文地址:https://www.cnblogs.com/sico/p/11638521.html

时间: 2024-11-13 09:56:19

高并发下的批量处理与单个处理(利用jdk8新特性处理,提高性能)的相关文章

高并发下的 Nginx 优化与负载均衡

高并发下的 Nginx 优化 英文原文:Optimizing Nginx for High Traffic Loads 过去谈过一些关于Nginx的常见问题; 其中有一些是关于如何优化Nginx. 很多Nginx新用户是从Apache迁移过来的,因些他们过去常常调整配置和执行魔术操作来确保服务器高效运行. 有一些坏消息要告诉你, 你不能像Apache一样优化Nginx.它没有魔术配置来减半负载或是让PHP运行速度加快一倍. 高兴的是, Nginx已经优化的非常好了. 当你决定使用Nginx并用a

高并发下的Nginx优化

高并发下的Nginx优化 2014-08-08 13:30 mood Nginx 过去谈过一些关于Nginx的常见问题; 其中有一些是关于如何优化Nginx. 很多Nginx新用户是从Apache迁移过来的,因些他们过去常常调整配置和执行魔术操作来确保服务器高效运行. AD:2014WOT全球软件技术峰会北京站 课程视频发布 11月21日-22日 与WOT技术大会相约深圳 现在抢票 过去谈过一些关于Nginx的常见问题; 其中有一些是关于如何优化Nginx. 很多Nginx新用户是从Apache

高并发下的业务提交策略(转)

出处:http://www.cnblogs.com/bobsoft/p/3622691.html 最近在考虑电商平台高并发下订单处理问题, 总结如下: 1.绝大部份的BS系统最大的性能瓶颈我觉得应该在DATABASE 为什么?因为其它影响因素(网络,存储,WEB服务器......),是可以通过投入比较快速的解决 网络?通过增加带宽解决:存储?通过存储设备或区域存储,即可解决大容量,可靠性问题: WEB服务器?可以通过四层或七层负 载均衡解决. 2.而DATABASE最大受限在INSERT,也就是

关于高并发下memcached可能出现的问题

首先,说说memcached的标准用法:memcached使用高效缓存,当有一些内容不是经常变动时,可以写入其中.如果有请求要获取这块数据,则优先从缓存中取出,仅当缓存过期,则从数据库获取实时数据,并再次更新到缓存中. 但如果网站频频出现高并发,比如说,将某块数据写入并设置有效时间为60s,但如果正好在60s后的那个瞬间,假如有10000个请求同时尝试获取这块数据,那么这10000个请求仍然只能通过数据库访问方式去获取,有没有办法缓解这种情况? 考虑利用memcache单个操作的原子性,使得10

高并发下的 Nginx 优化

英文原文:Optimizing Nginx for High Traffic Loads 过去谈过一些关于Nginx的常见问题; 其中有一些是关于如何优化Nginx. 很多Nginx新用户是从Apache迁移过来的,因些他们过去常常调整配置和执行魔术操作来确保服务器高效运行. 有一些坏消息要告诉你, 你不能像Apache一样优化Nginx.它没有魔术配置来减半负载或是让PHP运行速度加快一倍. 高兴的是, Nginx已经优化的非常好了. 当你决定使用Nginx并用apt-get,yum或是mak

高并发下怎么优化能避免服务器压力过大?

用户多,不代表你服务器访问量大,访问量大不一定你服务器压力大!我们换成专业点的问题,高并发下怎么优化能避免服务器压力过大? 1,整个架构:可采用分布式架构,利用微服务架构拆分服务部署在不同的服务节点,避免单节点宕机引起的服务不可用!2,数据库:采用主从复制,读写分离,甚至是分库分表,表数据根据查询方式的不同采用不同的索引比如b tree,hash,关键字段加索引,sql避免复合函数,避免组合排序等,避免使用非索引字段作为条件分组,排序等!减少交互次数,一定不要用select *! 3,加缓存:使

php结合redis实现高并发下的抢购、秒杀功能

原文: http://blog.csdn.net/nuli888/article/details/51865401 抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存来处理抢购,避免直接操作数据库,例如使用Redis.重点在于第二个问题 常规写法: 查询出对应商品的库存,看是否大于0,然后执行生成订单等操作,但是在判断库存是否大于0处,如果在高并发下就会有问

php 结合redis实现高并发下的抢购、秒杀功能

抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存来处理抢购,避免直接操作数据库,例如使用Redis.重点在于第二个问题 常规写法: 查询出对应商品的库存,看是否大于0,然后执行生成订单等操作,但是在判断库存是否大于0处,如果在高并发下就会有问题,导致库存量出现负数 [php] view plain copy <?php $conn=mysql_con

(高级篇)php结合redis实现高并发下的抢购、秒杀功能

抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存来处理抢购,避免直接操作数据库,例如使用Redis.重点在于第二个问题 常规写法: 查询出对应商品的库存,看是否大于0,然后执行生成订单等操作,但是在判断库存是否大于0处,如果在高并发下就会有问题,导致库存量出现负数 优化方案1:将库存字段number字段设为unsigned,当库存为0时,因为字段不能为负数