2015-08-05 17 views
5

Tôi gặp sự cố. Niềm tin của tôi là có một cái gì đó để làm với đồng thời hoặc đồng bộ hóa các chủ đề, mặc dù tôi không thể đặt ngón tay vào những gì đang xảy ra.Đồng thời ArrayList trên các kết nối ổ cắm

Đây là mô tả của tôi về luồng dữ liệu cho đối tượng FriendRequestList của chúng tôi.

Từ phía khách hàng, chúng tôi gửi yêu cầu kết bạn cho người dùng khác (người lao động). Vì vậy, chúng tôi gửi yêu cầu và thêm tên người dùng của chúng tôi vào danh sách User.incFriendReq của họ. Ví dụ này là ArrayList chỉ để tham khảo dễ tham khảo.

Vì vậy, bây giờ chúng tôi gửi yêu cầu tới máy chủ để nhận danh sách yêu cầu kết bạn của riêng chúng tôi (FriendRequestList.java).

Vì vậy, bây giờ là vấn đề. Nếu tôi sử dụng mã này bên dưới, người dùng sẽ không nhìn thấy yêu cầu kết bạn trước khi anh ta chấm dứt kết nối của mình (đăng xuất), điều này sẽ đóng kết nối. Khi anh ta đăng nhập, anh ta sẽ chỉ nhìn thấy yêu cầu trong danh sách của mình.

mã phía máy chủ:

... 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; 
} 

Khách hàng bên

... Giao tiếp n.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 
} 

Làm thế nào bao giờ hết, nếu tôi cập nhật Worker.java để làm điều này thay vì:

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

Trong khoảnh khắc người dùng khác yêu cầu tình bạn của tôi, tôi thấy yêu cầu trong danh sách của tôi. Điều gì mang lại? Điều này âm thanh với tôi như cơ sở hạ tầng cơ sở không được cập nhật, điều kiện chủng tộc hoặc một cái gì đó. Nhưng bản sửa lỗi là cách tôi truy xuất dữ liệu ở phía máy chủ, bằng cách sử dụng luồng.

Xin vui lòng một người nào đó giải thích và cũng làm thế nào điều này sẽ được thực hiện trong Java 7 trước khi suối sẽ giải quyết của tôi, với tôi, vấn đề tò mò.

Trên một lưu ý

Tôi muốn nói thêm rằng những người sử dụng được đặt bên trong một LinkedBlockingDeque và lấy từ đối tượng Data, một nguồn tài nguyên chia sẻ cho người lao động.

Trả lời

0

Dường như tôi muốn trả lại danh sách incFriendReq trực tiếp trong getFriendReq là một trong những nguồn của sự cố của bạn. Khi bạn sử dụng java 8 và dòng danh sách đó vào một danh sách mới, bạn chỉ cần tạo một bản sao, do đó không có bổ sung hữu ích. Nếu trường hợp này xảy ra, mã phía máy chủ của bạn cũng sẽ hoạt động sau đó bằng cách sử dụng new ArrayList<>(me.getFriends()).

Tôi sẽ xác minh rằng tất cả các truy cập vào danh sách được đồng bộ hóa chính xác và bạn biết vị trí và thời điểm danh sách đó bị đột biến.

+0

Điều thú vị về mã này là trong khi gỡ lỗi danh sách tôi nhận được từ 'getFriendReq' thực sự là kích thước một. Nhưng khi tôi nhận được vật thể ở phía bên kia nó có kích thước bằng không. – miniwolf

+0

Dường như với tôi rằng trạng thái danh sách của bạn ở phía máy chủ không được duy trì đúng cách. Danh sách có thể có kích thước bằng không vì bản sao cũ của danh sách vẫn còn trôi nổi ở đâu đó để được trả về nhưng không phải là danh sách giống như giá trị bạn đang xem (kiểm tra ID đối tượng trong trình gỡ lỗi của bạn để xác minh) hoặc có đồng thời vấn đề liên quan đến khả năng hiển thị bộ nhớ không hiển thị dữ liệu bị đột biến trên các chuỗi (đảm bảo tất cả các truy cập vào danh sách được đồng bộ hóa trên cùng một khóa). –

Các vấn đề liên quan