In the following methods, I have a list to keep the data and I can populate all the data into this menuDTOList
. However, when a send a new request after getting all the data from the first request, the menuDTOList
still keeps the data of the first request.
As there are 2 methods recursively calls each other, I cannot make the list to be cleared properly. I tried Collections.synchronizedList()
for thread-safety
, but it does not make any sense. Also tried to clear the list at different steps, but due to recursive method calls, it did not work correctly.
So, how can I clear the list values on each request while keeping them recursive calls between methodA
and methodB
?
public class Demo {
// private List<MenuDTO> menuDTOList = new ArrayList<>();
List<MenuDTO> menuDTOList =
Collections.synchronizedList(new ArrayList<MenuDTO>());
protected Iterable<MenuDTO> getData() {
for (...) {
methodA();
}
return menuDTOList;
}
private void methodA(final MenuItemExpandedDTO menuItemExpandedDTO) {
menuDTOList.add(dto);
for (...) {
methodB();
}
}
private void methodB() {
for (...) {
methodA(dto);
}
}
}
CodePudding user response:
If you do:
public class Demo {
protected Iterable<MenuDTO> getData() {
List<MenuDTO> menuDTOList = new ArrayList<>();
for (...) {
methodA(menuDTOList);
}
return menuDTOList;
}
private void methodA(final MenuItemExpandedDTO menuItemExpandedDTO, final List<MenuDTO> menuDTOList) {
menuDTOList.add(dto);
for (...) {
methodB(menuDTOList);
}
}
private void methodB(List<MenuDTO> menuDTOList) {
for (...) {
methodA(dto, menuDTOList);
}
}
}
Then each list instance is only used by a single thread, and the list will be available to be garbage collected as soon as the caller of getData
discards the reference.
CodePudding user response:
Could you please add more details, what is the condition of for
loops?
In the current state, I see 2 different problems here.
- methodA and methodB are calling each other, seems like the infinite loop problem
- Also if you want to make the list just thread-safe for setters, you can create a plain volatile list. Something like
volatile List<MenuDTO> menuDTOList = new ArrayList<>()
or if you're looking for out of the box data structure, you could useConcurrentLinkedQueue
. Or best of all, provide list as method param and avoid class level variable altogether