commit
d705c43194
@ -0,0 +1,113 @@ |
|||||||
|
package com.hfkj.schedule; |
||||||
|
|
||||||
|
import com.hfkj.common.security.SessionObject; |
||||||
|
import com.hfkj.common.security.UserCenter; |
||||||
|
import com.hfkj.common.utils.ListUtil; |
||||||
|
import com.hfkj.entity.BsUser; |
||||||
|
import com.hfkj.model.UserSessionObject; |
||||||
|
import com.hfkj.service.user.BsUserGradeService; |
||||||
|
import com.hfkj.service.user.BsUserService; |
||||||
|
import com.hfkj.service.user.impl.BsUserServiceImpl; |
||||||
|
import org.springframework.scheduling.annotation.Scheduled; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.concurrent.ArrayBlockingQueue; |
||||||
|
import java.util.concurrent.CountDownLatch; |
||||||
|
import java.util.concurrent.ThreadPoolExecutor; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
|
||||||
|
/** |
||||||
|
* @className: UserGradeSchedule |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2024/9/27 |
||||||
|
**/ |
||||||
|
@Component |
||||||
|
public class UserGradeSchedule { |
||||||
|
@Resource |
||||||
|
private BsUserService userService; |
||||||
|
@Resource |
||||||
|
private BsUserGradeService userGradeService; |
||||||
|
@Resource |
||||||
|
private UserCenter userCenter; |
||||||
|
|
||||||
|
@Scheduled(cron = "0 0 5 * * ?") // 每日凌晨05:00:00 执行一次
|
||||||
|
public void promote() { |
||||||
|
try { |
||||||
|
// 用户数据
|
||||||
|
List<BsUser> userList = userService.getList(new HashMap<>()); |
||||||
|
|
||||||
|
// 设备核心数目
|
||||||
|
int processorsNum = Runtime.getRuntime().availableProcessors(); |
||||||
|
|
||||||
|
Long startTime = System.currentTimeMillis(); |
||||||
|
System.out.println("本次更新任务开始"); |
||||||
|
// 初始化线程池
|
||||||
|
ThreadPoolExecutor threadPool = new ThreadPoolExecutor( |
||||||
|
processorsNum * 2, |
||||||
|
processorsNum * 2, |
||||||
|
4, |
||||||
|
TimeUnit.SECONDS, |
||||||
|
new ArrayBlockingQueue(processorsNum * 2 * 10), |
||||||
|
new ThreadPoolExecutor.DiscardPolicy()); |
||||||
|
|
||||||
|
// 大集合拆分成N个小集合,然后用多线程去处理数据,确保不会因为数据量过大导致执行过慢
|
||||||
|
List<List<BsUser>> splitNList = ListUtil.splitList(userList, 200); |
||||||
|
// 记录单个任务的执行次数
|
||||||
|
CountDownLatch countDownLatch = new CountDownLatch(splitNList.size()); |
||||||
|
// 对拆分的集合进行批量处理, 先拆分的集合, 再多线程执行
|
||||||
|
for (List<BsUser> singleList : splitNList) { |
||||||
|
// 线程池执行
|
||||||
|
threadPool.execute(new Thread(new Runnable(){ |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
//模拟执行时间
|
||||||
|
System.out.println("当前线程:"+Thread.currentThread().getName()); |
||||||
|
try { |
||||||
|
for (BsUser user : singleList) { |
||||||
|
try { |
||||||
|
// 等级晋升
|
||||||
|
userGradeService.promote(user.getId()); |
||||||
|
|
||||||
|
// 更新session
|
||||||
|
UserSessionObject session = new UserSessionObject(); |
||||||
|
session.setUser(userService.getUser(user.getId())); |
||||||
|
SessionObject sessionObject = new SessionObject(BsUserServiceImpl.userToken(user.getId()), session); |
||||||
|
userCenter.save(sessionObject); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
System.out.println("更新油站失败"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
System.out.println("更新油站出现异常"); |
||||||
|
System.out.println(e.getMessage()); |
||||||
|
} finally { |
||||||
|
// 任务个数 - 1, 直至为0时唤醒await()
|
||||||
|
countDownLatch.countDown(); |
||||||
|
} |
||||||
|
} |
||||||
|
})); |
||||||
|
} |
||||||
|
try { |
||||||
|
// 让当前线程处于阻塞状态,直到锁存器计数为零
|
||||||
|
countDownLatch.await(); |
||||||
|
} catch (Exception e) { |
||||||
|
System.out.println("系统出现异常"); |
||||||
|
} |
||||||
|
Long endTime = System.currentTimeMillis(); |
||||||
|
Long useTime = endTime - startTime; |
||||||
|
System.out.println("本次更新任务结束,共计用时"+useTime+"毫秒"); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
System.out.println("更新价格失败!!!"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,56 @@ |
|||||||
|
package com.hfkj.common.utils; |
||||||
|
|
||||||
|
import com.alibaba.excel.util.CollectionUtils; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* 集合工具类 |
||||||
|
* @className: ListUtil |
||||||
|
* @author: HuRui |
||||||
|
* @date: 2024/9/27 |
||||||
|
**/ |
||||||
|
public class ListUtil { |
||||||
|
|
||||||
|
/** |
||||||
|
* 拆分集合 |
||||||
|
* |
||||||
|
* @param <T> 泛型对象 |
||||||
|
* @param resList 需要拆分的集合 |
||||||
|
* @param subListLength 每个子集合的元素个数 |
||||||
|
* @return 返回拆分后的各个集合组成的列表 |
||||||
|
**/ |
||||||
|
public static <T> List<List<T>> splitList(List<T> resList, int subListLength) { |
||||||
|
if (CollectionUtils.isEmpty(resList) || subListLength <= 0) { |
||||||
|
return new ArrayList<>(); |
||||||
|
} |
||||||
|
List<List<T>> ret = new ArrayList<>(); |
||||||
|
int size = resList.size(); |
||||||
|
if (size <= subListLength) { |
||||||
|
// 数据量不足 subListLength 指定的大小
|
||||||
|
ret.add(resList); |
||||||
|
} else { |
||||||
|
int pre = size / subListLength; |
||||||
|
int last = size % subListLength; |
||||||
|
// 前面pre个集合,每个大小都是 subListLength 个元素
|
||||||
|
for (int i = 0; i < pre; i++) { |
||||||
|
List<T> itemList = new ArrayList<>(subListLength); |
||||||
|
for (int j = 0; j < subListLength; j++) { |
||||||
|
itemList.add(resList.get(i * subListLength + j)); |
||||||
|
} |
||||||
|
ret.add(itemList); |
||||||
|
} |
||||||
|
|
||||||
|
// last的进行处理
|
||||||
|
if (last > 0) { |
||||||
|
List<T> itemList = new ArrayList<>(last); |
||||||
|
for (int i = 0; i < last; i++) { |
||||||
|
itemList.add(resList.get(pre * subListLength + i)); |
||||||
|
} |
||||||
|
ret.add(itemList); |
||||||
|
} |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue