我有一个 REST 项目,在访问控制服务类中保存用户的MảngDanh sách
。一切都工作正常,直到 REST Web 服务突然抛出 java.util.NoSuchElementException
。单步查看代码,我意识到 ArrayList 很奇怪:
- 在逐步执行过程中将鼠标悬停在 Eclipse 中的字段上会导致调用方法时发生
com.sun.jdi.InitationException。
。经过一些研究,似乎当 toString()
定义不正确时就会发生这种情况。嗯,我不确定这里的错误是什么意思。
MảngDanh sách
的大小为 -1
。
重新启动服务器后问题消失,但我需要知道是什么导致了这种情况发生。有人有什么想法吗?
biên tập
有人要求提供代码,所以我将粘贴与列表相关的部分。
@Service
@Giao dịch
public class AccessControlServiceImpl implements AccessControlService {
@Autowired
private OnlineUserTracker userTracker;
@Autowired
private UserDAO userDao;
public boolean checkAuthorized(String username) {
User user = userDao.findById(username);
// Other logic
userTracker.getUsers().add(user); // If user is authorized
}
public void logoff(String username) {
userTracker.removeUser(username);
}
}
public class OnlineUserTracker {
private List users;
public OnlineUserTracker() {
this.users = new ArrayList<>();
}
public List getUsers() {
return users;
}
public void setUsers(List users) {
this.users = users;
}
public User getUserFromUsername(String username) {
for (User user : users) {
if(user.getUsername().equals(username)) {
return user;
}
}
return null;
}
public void removeUser(String username) {
User user = getUserFromUsername(username);
if (user != null) {
users.remove(user);
}
}
}
假设问题是并发不正确,一个好的解决方案是将所有与列表的交互包装在 OnlineUserTracker 中,然后同步相关方法(这意味着任何方法都不应返回底层列表)。事实上,无论您如何解决问题,最好不要将 List 暴露给 OnlineUserTracker 之外的代码(即封装)。
一个“简单”的解决方案是使 List 成为 CopyOnWriteArrayList 的实例。此实现对于正常交互和迭代来说是线程安全的。但是,如果您频繁添加或删除用户,效率可能会较低。
Tôi là một lập trình viên xuất sắc, rất giỏi!