跨插槽连接的ArrayList并发

时间:2015-08-05 12:17:35

标签: java multithreading sockets arraylist

我有一个问题。我的信念是,它与并发或线程同步有关,尽管我无法理解正在发生的事情。

以下是我对FriendRequestList对象的数据流的描述。

从客户端我们向另一个用户(工作人员)发送好友请求。 因此,我们发送请求并将自己的用户名添加到User.incFriendReq列表中。该实例是一个ArrayList,仅供参考。

现在我们将请求发送到服务器以接收我们自己的好友请求列表(FriendRequestList.java)。

所以现在问题。如果我在下面使用此代码,则用户在终止其连接(注销)之前将不会看到朋友请求,这将关闭连接。当他登录时,他只会在他的列表中看到该请求。

服务器端代码:

...... Worker.java ......

private Object getFriendRequests() {
    User me = Data.getUser(myUserName);
    if ( me == null ) {
        return new NoSuchUserException(); // Don't worry about it ;)
    }

    return new FriendRequestList(me.getFriendReq());
}

... User.java ...

private List<String> incFriendReq;

public List<String> getFriendReq() {
    return incFriendReq;
}

客户端

...... Communication.java ......

public FriendRequestList getRequests() {
    sendObject(new GetRequests());
    return inputHandler.containsRequests();
}

... MessageListener.java ...

public void run() {
    ...
    FriendRequestList requests = communication.getRequests();
    update(requestList, requests);
    // Here we have the problem. requests.size is never different from 0
}

但是,如果我更新Worker.java来代替这样做:

private Object getFriendRequests() {
    User me = Data.getUser(myUserName);
    if ( me == null ) {
        return new NoSuchUserException();
    }
    return new FriendList(me.getFriends().stream().collect(Collectors.toList()));
}

当其他用户请求我的友谊时,我在列表中看到了请求。 是什么赋予了?这听起来像基础数据结构没有更新,竞争条件或其他东西。 但修复方法是如何通过使用流来检索服务器端的数据。

请有人解释一下,在流式解决我的好奇问题之前,如何在Java 7中完成此操作。

注意事项

我想补充说,用户被放置在LinkedBlockingDeque内,并从Data对象中检索,这是工作人员的共享资源。

1 个答案:

答案 0 :(得分:0)

我认为直接在incFriendReq中返回getFriendReq列表是您问题的根源之一。当您使用java 8并将该列表流式传输到新列表时,您只是制作副本,因此没有有用的添加。如果是这种情况,那么您的服务器端代码也可以使用new ArrayList<>(me.getFriends())

我会验证对列表的所有访问是否已正确同步,并且您知道该列表在何处以及何时发生变异。