代码之家  ›  专栏  ›  技术社区  ›  Jai

Java:损坏的ARARYLIST?

  •  1
  • Jai  · 技术社区  · 6 年前

    我有一个休息项目 ArrayList 访问控制服务类中的用户。一切正常,直到rest web服务突然抛出 java.util.NoSuchElementException 。通过密码,我意识到 数组列表 怪异:

    1. 在步骤到原因期间在eclipse中鼠标悬停在字段上 com.sun.jdi.InvocationException occurred invoking method. 。经过一些研究,这似乎发生在 toString() 定义不正确。好吧,我不知道这里不正确的意思是什么。
    2. 的大小 数组列表 -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);
            }
        }
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   jtahlborn    6 年前

    假设问题是不正确的并发性,一个好的解决方案是在onlineusertracker中包装与列表的所有交互,然后同步相关的方法(这意味着任何方法都不应该返回底层列表)。事实上,不管您如何解决问题,最好不要将列表公开给OnlineUserTracker之外的代码(即封装)。

    一个“简单”的解决方案是使列表成为copyonwritearraylist的实例。对于正常的交互和迭代,这个实现是线程安全的。但是,如果您经常添加或删除用户,则可能效率较低。

        2
  •  0
  •   Szychan    6 年前

    所以从我的观点来看,很多事情都可能出错。

    但如果你得到了arraylist,你说它的大小是-1。那是威德。 list.size()不应返回负值。

    另一方面,如果您试图获取列表中对象的索引,而该对象不在该列表中,则可能会发生这种情况…

    很可能就是这样。其原因可能是从其他线程访问该列表并在indexof()方法调用之前将其删除。或者向服务器发送两个请求。第二个请求显然会产生这样的问题:)