Reputation: 25
I have a service class that adds elements to a set and there is a scheduled job method that executes after every 2 seconds which reads all the elements added to the set (the one in which service adds elements) and at the end, it clears the whole set.
I am confused if some element gets added to the list between I am reading the data from the set or between the time after I am done reading data from the set and before clearing the set then that element will be lost.
How can I make sure no element gets added to the set while the scheduled job is not finished?
EventService.java
public void foo(){
eventSet.add(new Event("event description"));
}
EventJob.java
@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();
}
Upvotes: 0
Views: 859
Reputation: 61
As my understanding, you can create a thread control for this behavior,
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();
}
Upvotes: 1
Reputation: 409
You should be aware that if you are in a multiple machine cluster other problems will arise that will not be solved by this "in-memory" solution.
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);
}
}
Edited after op clarification!
Upvotes: 0
Reputation: 761
If you don't want to be added to the set while running the scheduled job means you have to maintain some flags based on some set limits and enable that AtomicBoolean to true when the when you reached the limit "false" once you have cleared the set. Below is the pseudo code,
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)
}
Upvotes: 0