异步 线程 堆积问题?

上次的异步使用的是spring自带的 后经人提醒使用

//...
这个...代表上文代码  这整个方法是毫秒级执行  反正就是1s执行好多次

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
 scheduler.scheduleWithFixedDelay(new Runnable() {
                    @Override
                    public void run() {
                //redis保存数据
                }
}, 0, 5, TimeUnit.SECONDS);

//...

我的初心是:每隔5s保存一次到redis

但是现在出现的问题是:并没采取理想那样执行 而是线程达到5后,任务开始进入队列(看了下队列达到最大值 将采取拒绝策略) 之后数据每次保存全部都是最大队列数保存(一次将20左右的保存) 还变成了每秒

那我现在就想到了既然这样 我可不可以 最大线程1 空闲线程1 队列长度1(那个有界堵塞队列) 拒绝策略 这样组一个线程池 可以吗 或者还有其他方式 (求解 给点意见吧)

经过实验多次 终于解决了 看看我的实现过程吧 绞尽脑汁了
1.首先单独new线程不行(不能一进方法就new一次吧 那不直接爆掉)

2.线程池(自定义的 将各个参数都设定1 但这时线程数是1了但别忘了 堆积的任务会放到队列中 但是队列的数量好像不能设置吧 所以可能会出现5s保存一次队列中的数据 所以也不能实现)这个没试 我在试错中 想到这种方式的结果 感觉不可行

3.使用spring的异步 这个在第一次试了 我是没成功 还要改掉默认的线程池 我当时是让线程睡眠5s在保存 结果没成功

4.这个我实验了且成功了。 方法是:在这个方法中将数据保存到set中 ,当然只保存一条就够了,做下逻辑即可(为什么set 我是怕数据重复才采用的),然后在这个方法的下方设定了个定时任务(spring自带的)每5s执行一次 ,执行内容就是redis保存这个set(当然为空这些,做做处理逻辑 ) 保存完清空set

回复
阅读 732
3 个回答
✓ 已被采纳

光从描述来看,感觉楼主是调用问题
scheduler.scheduleWithFixedDelay(new Runnable() {

                @Override
                public void run() {
            //redis保存数据
            }

}, 0, 5, TimeUnit.SECONDS);
这个地方是不是调用了多次,

有点不太理解楼主的问题,如果只是每隔5s做一次保存至redis的操作,只需要一个线程每隔5s做一次即可,为什么会存在线程数持续增加的情况?可以描述地更清楚一点么

每隔5s保存一次到redis,要不咱用用延时队列

推荐问题
宣传栏