我有一个问题。我的信念是,它与并发或线程同步有关,尽管我无法理解正在发生的事情。
以下是我对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
对象中检索,这是工作人员的共享资源。
答案 0 :(得分:0)
我认为直接在incFriendReq
中返回getFriendReq
列表是您问题的根源之一。当您使用java 8并将该列表流式传输到新列表时,您只是制作副本,因此没有有用的添加。如果是这种情况,那么您的服务器端代码也可以使用new ArrayList<>(me.getFriends())
。
我会验证对列表的所有访问是否已正确同步,并且您知道该列表在何处以及何时发生变异。