Java定时器任务和点击事件共存冲突时の解决方案【广告展示场景】

首先我们来复盘一下需求情况

需求:现在需要在系统设置一个广告信息,广告信息要有【开始时间】和【结束时间】,在【开始时间】和【结束时间】之间广告是处于【展示】状态,不在这个时间段内的广告都处于【不展示】状态。

PS:这里同时包含了定时器自动判断【当前时间】和广告【开始时间】&【结束时间】的关系,自动更新广告的展示状态。同时还有用户修改广告展示状态的点击事件任务。这两者理论上是矛盾和冲突的。来看看我们的定时器执行的任务:

在这里插入图片描述


难点场景: 当用户手动修改广告的【展示状态】时,假如说

  • [1]、当系统后台把广告创建在【开始时间】之前,此时我们的广告由于未达到开始展示的时间,所以当前广告本应该处于【不展示】状态。但是此时后台手动设置该广告为【展示】状态,这个状态需要一直保持到【结束时间】,过了结束时间之后定时器将会把这个状态改为【不展示状态】。任务执行图如下:

在这里插入图片描述

  • [2]、同理,当创建广告的时间恰好处于广告的【开始时间】和【结束时间】之间,此时广告本为【展示】状态,但是我们手动修改了该广告的状态为【不展示】。此时手动修改的广告状态【不展示】和定时器自动执行的更新【不展示】广告为【展示】状态的事件冲突,这个手动设置的【不展示】状态将会一直保持下去,具体如图:

在这里插入图片描述


其实以上场景的冲突在使用定时器的时候经常会发生,这里就简单讲一下三种解决方案
1、通过使用MySQL的两个字段来进行 过滤&更新
定义两个字段:【isShow】[0] 不展示 [1]展示 【operationStatus】[0]非手动修改 [1]手动修改

思路:主要还是以定时器为主线,以定时器为主任务,让定时器去过滤掉手动修改过的信息内容 ,手动修改过的信息不会被定时器再次修改,但是如果说两个时间点的状态相同则手动操作的信息还是要回到定时器的更新范围内。(关键点:当我们isShow所对应的状态值与我们当前所处时间点对应广告时间点相同时<比如我们当前时间点为开始时间前,此时我们的广告isShow字段应该是0不展示。如果说此时我们数据库保存的广告展示状态isShow字段也是0并处于广告展示开始时间前,那么就是二者时间点相同>,并且当我们operationStatus非0的时候,只要二者时间点对应的状态值相同就一定要更新【operationStatus】字段值为0,这是为了释放手动修改操作导致的过滤,重新让定时器接管我们当前的广告信息)

伪代码
1、获取定时器要跟踪更新的广告集合内容
2、对广告集合进行判空
3、获取当前的系统时间(时间戳)
4for(广告集合)
	  根据(当前时间 & 开始时间 & 结束时间)判断当前系统时间下isShow的状态值是展示还是不展示
5if(当前时间点的状态字段isShow == 数据库保存的当前广告时间点状态isShow && 数据库保存的operationStatus > 0{	  
	  	更新其operationStatus = 0
   } else {
		if(operationStatus == 0)	
   	       	更新数据库中的isShow为当前时间点对应的isShow状态
   }
以此类推,以下两种方案参考如上进行实现即可:
  • 通过使用Redis保存数据来进行 过滤&更新:手动操作的广告以id为key保存到reids并设置定时过期,定时器判断该广告的id是否在redis中存在key…
  • 通过使用锁来进行 过滤&更新:加锁主要是锁到时间节点的时候,进行锁的释放操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值