多线程的Furture应用(一)

本文探讨了一启才福上线Spider后遇到的性能问题及其解决方案,包括验证码处理、接口响应时间缩短、系统耦合度降低及多线程优化等方面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一启才福上线spider之后,开始关注程序的性能问题,比较典型的问题出了几个。


1、关于登录图片验证码,在非docker环境,共享session情况,服务器存储的是request中的param中,docker环境下,每次请求可能被不同的服务器处理,导致错误。最终使用通过本地cookie存储key_,然后存储/查询redis中的方式解决。


2、每日收益等接口数据响应时间长。

通过每日定时任务,保存数据的方式(接口数据静态化),减短响应时间。


3、系统容错耦合度高的问题

以收银台发的支付通知为例,需要多步处理。1、本地处理更新订单数据,2、通知产品中心支付接口。3、添加分销数据。4、发送邮件 5、更新用户新手状态 等,6返回状态码。

系统接了子渠道后,需要再添加一个功能,7、通知子渠道的通知状态,如果其中某一步出错,就需要产品中心不断的发定时通知,这显然是合理的。

通过本地订单状态,通过定时任务给子渠道发送订单状态。降低了系统之间的强依赖,减低了系统之间耦合度。


4、程序响应时间长的问题。

以收银台通知支付结果为例: 需要6-7步完成,考虑3把不相关的步骤多线程异步处理下。

1、考虑过时间监听器,给多个任务publishEvent方式分配不同的时间监听。

2、通过nio,设置缓冲区,比如rabbitMq消息队列方式去处理。

3、使用Furture方式,以下便是多线程一个简单应用。


比如,以做饭为例(假定步骤可能存在不合理),
1、从网上购买刀具,切菜板 

2、去超市购买蔬菜,米面油

3、收到快递 及蔬菜到家后,开始做饭。


public class OnlineShopping implements Runnable{
     private Knife knife;

    @Override
    public void run() {
        System.out.println("第一步:下单");
        System.out.println("第二步:等待送货");
        try {
            Thread.sleep(10000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("第三步:快递送到");
        knife=new Knife();
    }

    public Knife getKnife() {
        return knife;
    }
}
public class MarketShopping implements Runnable{
    private Vegetable vegetable;
    @Override
    public void run() {
        System.out.println("第一步:去超市");
        System.out.println("第二步:挑选蔬菜");
        try {
            Thread.sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("第三步:菜带回家");
        vegetable=new Vegetable();
    }

    public Vegetable getVegetable() {
        return vegetable;
    }
}
public class CommonCook {
    public static void main(String[] args) throws InterruptedException{
        //第一步
        long startTime = System.currentTimeMillis();
        OnlineShopping onlineShopping=new OnlineShopping();
        Thread thread=new Thread(onlineShopping);
        thread.start();
        MarketShopping marketShopping=new MarketShopping();
        Thread thread2=new Thread(marketShopping);
        thread2.start();
        thread.join();
        thread2.join();
        System.out.println("准备工作用时" + (System.currentTimeMillis() - startTime) + "ms,开始展示厨艺");
        cook(onlineShopping.getKnife(),marketShopping.getVegetable());
        System.out.println("饭做好总共用时" + (System.currentTimeMillis() - startTime) + "ms");
    }
    public static void cook(Knife knife,Vegetable vegetables){
        try {
            // 模拟做饭时间
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


第一步:下单
第二步:等待送货

第一步:去超市
第二步:挑选蔬菜
第三步:菜带回家
第三步:快递送到
准备工作用时10004ms,开始展示厨艺
饭做好总共用时20004ms

实现Runnable接口创建线程, 缺陷就是在执行完任务之后无法获取执行结果,使用thread.join(); 等待进程做完。

Callable 和 Runnable 都是执行的任务的接口,区别在于Callable有返回值,而Runnable无返回值。

下一篇,开始改造代码。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大巨魔战将

如果对您有帮助,请打赏1分钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值