首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在SpringBoot中以线程安全的方式执行@调度作业?

如何在SpringBoot中以线程安全的方式执行@调度作业?
EN

Stack Overflow用户
提问于 2021-01-12 15:18:05
回答 3查看 301关注 0票数 0

我有一个服务类,它将元素添加到一个集合中,并且有一个计划作业方法,它每隔2秒执行一次,它读取添加到集合的所有元素(服务添加元素的元素),在结束时,它清除整个集合。

我感到困惑的是,在从集合读取数据之间,还是在从集合读取数据之前,或者在清除集合之前,是否会将某些元素添加到列表中。

如何确保在计划作业未完成时没有任何元素被添加到集合中?

EventService.java

代码语言:javascript
复制
public void foo(){
    eventSet.add(new Event("event description"));
}

EventJob.java

代码语言:javascript
复制
@Autowired
EventService eventService;

@Scheduled(cron = "${cron.expression.for.every.2.second}")
private void job(){
    for(Event event : eventService.getEventSet()){
         //process event
         System.out.println(event);
    }
    eventService.getEventSet().clear();
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-01-13 19:12:24

据我理解,您可以为此行为创建一个线程控件,

代码语言:javascript
复制
private static ReentrantLock listLock = new ReentrantLock();

  private void readSomeData() {
    // Get the lock of object
    listLock.lock();

    // read list

    // free the lock
    listLock.unlock();
  }

  @Scheduled(cron = "${cron.expression.for.every.2.second}")
  private void job() {
    // Check lock is free or not
    if (!listLock.isLocked()) {
      // Get the lock of object
      listLock.lock();
      for (Event event : eventService.getEventSet()) {
        // process event
        System.out.println(event);
      }
      eventService.getEventSet().clear();
    }
    // free the lock
    listLock.unlock();
  }
票数 1
EN

Stack Overflow用户

发布于 2021-01-12 15:55:32

您应该知道,如果您处于多台机器集群中,则会出现其他问题,这些问题不会通过这种“内存中”解决方案得到解决。

代码语言:javascript
复制
private AtomicBoolean isRunning = new AtomicBoolean(false);

public void job(){
     Set<YourObject> events = eventService.getEventSet();
     if (isRunning.compareAndSet(false, true)) {
        for(Event event : events){
            //process event
        }
       
        eventService.getEventSet().clear();
        isRunning.compareAndSet(true, false);
     }
     
}

编辑后,op澄清!

票数 0
EN

Stack Overflow用户

发布于 2021-01-13 00:57:37

如果您不想在运行计划作业时被添加到集合中,就意味着您必须维护一些基于某些设置限制的标志,并在清除集合后达到"false“限制时启用该AtomicBoolean。下面是伪代码,

代码语言:javascript
复制
AtomicBoolean canAddData = new AtomicBoolean(true);

public void foo(){
    if(canAddData){ // here instead of atomicboolean you can use eventSet.size()==10 as well if you want to be added based on some level size.
      eventSet.add(new Event("event description"));
      canAddData.set(eventSet.size() <= 10)
   }
}

// scheduler code 
public void processEvents() {
     Iterator<Event> eventIter = eventSet.iterator()
     while(eventIterator.hasNext()) {
          Event = eventIterator.remove()
          // Process event here and clearing item one by one
     }
     canAddData.set(true)
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65686776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档