多线程分批处理数据

需求:

目前蚂蚁课堂有10万个用户,现在蚂蚁课堂需要做活动,给每一个用户发送一条祝福短信

思路:
多线程分批处理数据_第1张图片
就是将数据分成几个部分,这里用集合。然后使用多线程进行异步发送
步骤
1.初始化数据
2.定义每个线程分批发送大小
3.计算每个线程需要分批跑的数据
4.进行分批发送

实例:
实体类:

package com.emple.entity;

import java.security.SecureRandom;

/**
 * @author shkstart
 * @date 2019/6/5- 16:14
 */
public class UserEntity {
    private String userId;
    private String userName;

    public UserEntity() {
    }

    public UserEntity(String userId, String userName) {
        this.userId = userId;
        this.userName = userName;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Override
    public String toString() {
        return "UserEntity{" +
                "userId='" + userId + '\'' +
                ", userName='" + userName + '\'' +
                '}';
    }
}

这里要用到一个分页工具,将List数据分割为几个list
工具类 ListUtils:

package com.emple;

import java.util.ArrayList;
import java.util.List;

public class ListUtils {
	/**
	 *
	 * @methodDesc: 功能描述:(list 集合分批切割)
	 * @author: 余胜军
	 * @param: @param
	 *             list
	 * @param: @param
	 *             pageSize
	 * @param: @return
	 * @createTime:2017年8月7日 下午9:30:59
	 * @returnType:@param list 切割集合
	 * @returnType:@param pageSize 分页长度
	 * @returnType:@return List> 返回分页数据
	 * @copyright:上海每特教育科技有限公司
	 */

	static public <T> List<List<T>> splitList(List<T> list, int pageSize) {
		int listSize = list.size();
		int page = (listSize + (pageSize - 1)) / pageSize;
		List<List<T>> listArray = new ArrayList<List<T>>();
		for (int i = 0; i < page; i++) {
			List<T> subList = new ArrayList<T>();
			for (int j = 0; j < listSize; j++) {
				int pageIndex = ((j + 1) + (pageSize - 1)) / pageSize;
				if (pageIndex == (i + 1)) {
					subList.add(list.get(j));
				}
				if ((j + 1) == ((j + 1) * pageSize)) {
					break;
				}
			}
			listArray.add(subList);
		}
		return listArray;
	}
}

发送类:

package com.emple;

import com.emple.entity.UserEntity;

import javax.annotation.processing.SupportedSourceVersion;
import java.util.ArrayList;
import java.util.List;

/**
 * @author shkstart
 * @date 2019/6/5- 16:17
 */
class UserSendThread implements Runnable{
    private List<UserEntity> listUser;
    public UserSendThread(List<UserEntity> listUser){
        this.listUser = listUser;
    }
    @Override
    public void run() {
        for (UserEntity userEntity :listUser){
            System.out.println("线程name:"+Thread.currentThread().getName()+userEntity.toString());
        }
        System.out.println();
    }
}


public class BatchSms {
    public static void main(String[] args) {
        //1.初始化数据
        List<UserEntity> initUser = initUser();
        //2.定义每个线程分批发送大小
        int userCount = 2;
        //3.计算每个线程需要分批跑的数据
        List<List<UserEntity>> lists = ListUtils.splitList(initUser, userCount);
        for (int i = 0; i < lists.size(); i++) {
            List<UserEntity> userEntities = lists.get(i);
            UserSendThread userSendThread = new UserSendThread(userEntities);
            Thread thread = new Thread(userSendThread,"线程"+i);
            thread.start();

        }
        //4.进行分批发送

    }
   static private List<UserEntity> initUser(){
        ArrayList<UserEntity> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(new UserEntity("userId:"+i,"userName:"+i));
        }
        return list;
    }
}

运行结果:
多线程分批处理数据_第2张图片
注意:
小项目可以这样实现,大项目不行。因为大项目考虑数量,用线程池管理 mq实现

你可能感兴趣的:(java)