java - Java:损坏的 ArrayList?
问题描述
我有一个 REST 项目,我在其中将一个ArrayList
用户保留在访问控制服务类中。一切正常,直到 REST Web 服务突然抛出一个java.util.NoSuchElementException
. 浏览代码,我意识到这ArrayList
很奇怪:
- 在逐步执行原因期间将鼠标悬停在 Eclipse 中的字段上
com.sun.jdi.InvocationException occurred invoking method.
。经过一些研究,似乎在toString()
定义不正确时会发生这种情况。好吧,我不确定这里的错误是什么意思。 - 的大小
ArrayList
是-1
。
重新启动服务器后问题消失了,但我需要知道是什么导致了这种情况发生。有人有什么想法吗?
编辑
有人要求提供代码,所以我将粘贴与列表相关的部分。
@Service
@Transactional
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<User> users;
public OnlineUserTracker() {
this.users = new ArrayList<>();
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> 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 的一个实例。此实现对于正常交互和迭代都是线程安全的。但是,如果您经常添加或删除用户,则效率可能会降低。
推荐阅读
- asp.net-mvc - 为 ASP.NET MVC 5 项目设计更复杂的数据库
- java - 是否可以强制转换方法?
- swift - 插入的模型看起来比预期的大并且在相机的背面
- python - 使用 Keras 的慢 DQN
- python - 如何将具有每日收益的数据框转换为从 100 开始的数据框索引
- c - TCP/IP 流转储任意簇中的文本(C 套接字编程)
- python - 如何在小复杂度模型(LBCNN)上解决 Pytorch “CUDA out of memory”
- amazon-web-services - 针对 PCI DSS 的 Elastic Beanstalk 的内部漏洞扫描和笔测试
- identityserver4 - 如何向 microsoft-identity-web 提供 login_hint
- c# - Unity LookAt 函数破坏了游戏对象