如何同步两种方法

Mon*_*ael 2 java collections concurrency multithreading

我在Java中有以下代码用于聊天服务器应用程序 -

public synchronized List<ChatMessage> getMessages(int messageNumber) {
    return messages.subList(messageNumber + 1, messages.size());
}

public synchronized int addMessage(ChatMessage c) {
    messages.add(c);
    return messages.size()-1;
}
Run Code Online (Sandbox Code Playgroud)

我有以下测试代码 -

public static void main(String[] args) {
    final ChatRoom c = new ChatRoom();
    Thread user1 = new Thread(new Runnable() {
        public void run() {
            for(int i=0;i<1000;i++) {
                c.addMessage(new ChatMessage());
                c.getMessages(0);
            }
        }
    });
    Thread user2 = new Thread(new Runnable() {
        public void run() {
            for(int i=0;i<1000;i++) {
                c.addMessage(new ChatMessage());
                c.getMessages(0).size();
            }
        }
    });
    user1.start();
    user2.start();
}
Run Code Online (Sandbox Code Playgroud)

我收到了ConcurrentModificationException.

这怎么可能?

Jon*_*eet 6

这怎么可能?

您的getMessages方法只返回原始列表中的视图.它不会创建列表的副本.因此,一个线程正在使用列表上的视图,而另一个线程则修改列表 - 此时,您将获得异常.

来自以下文档List.subList:

如果支持列表(即此列表)在结构上以除返回列表之外的任何方式进行修改,则此方法返回的列表的语义将变为未定义.(结构修改是那些改变了这个列表的大小,或以其他方式扰乱它的方式,正在进行的迭代可能会产生不正确的结果.)

目前还不清楚你在这里想要实现的是什么,但从根本上说你不能subList用来神奇地创建一个线程安全列表:)

  • 乔恩双向飞碟回答了我的问题!:-O问题刚刚解决了.:-) (2认同)