java跑批_【多线程应用】使用java自带线程池开发一个跑批程序

前言

多线程是java的比较重要的特性之一,现在记录一个使用多线程解决实际问题的栗子

背景

假设有一个模型服务,它的功能是通过输入的手机号来计算分数。例如支付宝的芝麻分。现在我有一个很大的客户手机号集合,数据量集是百万级别的。产品的要求是用尽可能短的时间将客户手机号集合中的每一个手机号都要匹配出分数。

可行性分析

假设模型服务成功处理一笔交易的时间是50ms,如果使用传统单线程的方式,每秒最多处理20笔交易。即TPS=20。假如需要跑批的数据量是100w,成功处理完这些数据需要消耗 100w/ 7.2w=13.8小时。假设我们模型服务的系统处理能力可以达到每秒中成功处理100笔交易,那么 成功处理完这些数据只消耗 100w/36w=2.7小时,缩短了 11个小时。

首先了解一种线程池

java 自带的线程池中有一个固定大小线程池

newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待

核心思想

我们将访问模型服务这个行为通过线程来实现,这个线程的任务就是通过访问评分服务将一个手机号的分数记录下来。首先我们维护一个长度为1000的定长线程池,在向线程池添加工作线程时,通过控制线程加入线程池的时间间隔 来实现控制tps。比如我们需要控制tps是 100,我们可以设置添加线程的间隔是 10ms,即每一秒最多有100个线程加入到线程池。这样就可以实现以tps100的方式来访问评分服务。注意,这里的tps是期望tps,实际tps可能达不到100。

关键代码

WorkThread

package com.batch.threadapp;

public class WorkThread implements Runnable{

private String mobile = "";

private Integer num;

public WorkThread(String _mobile,Integer num){

this.mobile = _mobile;

this.num=num;

}

@Override

public void run() {

String reqData = mobile;

try {

System.out.println("["+num+"]request data :"+reqData);

String respStr = accessScoreService(reqData);

System.out.println("["+num+"]response data :"+respStr);

} catch (Exception e) {

System.out.println(e.getMessage());

}

}

//TODO 在这里写访问评分服务的逻辑,通常是http的

private String accessScoreService(String reqData) {

return reqData+"res";

}

}

Main

package com.batch.threadapp;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class Main {

public static void main(String[] args) {

List mobList=new ArrayList();

mobList.add("18654444444");

mobList.add("18654444443");

mobList.add("18654444442");

Integer tps=10;

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1000);

int sleepTime = 1000 / tps;

for(Integer i=0,size=mobList.size();i

String mob=mobList.get(i);

fixedThreadPool.execute(new WorkThread(mob, i));

try {

Thread.sleep(sleepTime);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("线程初始化完成");

}

}

后记

到目前为止,简单的跑批程序已经写完。但是有一个问题是程序什么时候可以停止未知。即在主线程中,无法得知子线程的处理情况。这个问题留在以后解答。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值