ArrayList,检查2个线程

时间:2015-12-28 21:43:26

标签: java multithreading arraylist copyonwritearraylist

我有一个清单:

ArrayList list = new ArrayList<>();

在第一个帖子上我添加了元素(它很快 - 30 /秒) 在第二个线程上,我读取它的大小并打印到文件。

第一个帖子:

synchronized(list){
    list.add(PlayerPosition);
}

第二个帖子:

synchronized(list){
if(list.size()>0)
    out.print(list.size() + " ");
}

它是文件的输出,只是一部分: 1 1 1 3 3 5 4 6 7 7 9 11 8 9 12 10 14 16

这是错误的,因为它应该只增加。可以有1 1 1,但不能是11 8。

我的程序很大,但这些只出现在这个列表中(我删除了一半的代码来调试它)。整个应用程序中没有list.remove()等。

我有一个问题:这是可能的,它是这样的吗? 否则 - 在代码中的某处是我的错。

是的,我尝试过CopyOnWriteArrayList - 同样的事情。 谢谢!

2 个答案:

答案 0 :(得分:1)

print可能没有按照您期望的顺序执行。将第二个线程的代码更改为以下内容:

synchronized(list){
    if (list.size() > 0) {
        synchronized (out) {
            out.print(list.size() + " ");
            out.flush();
        }
    }
}

您的OutputStream正在将字符写入终端(或文件或其他内容)。如果没有out上的同步和刷新,当线程2告诉OutputStream打印时,之前的打印可能尚未完成。同步和刷新强制线程2等到所有字符实际写入终端后再继续。

答案 1 :(得分:1)

您可以通过以下几种方式改进代码。首先,您不必自己实现同步原语。 Java已经内置了SynchronizedList。请参阅Collections.synchronizedList(list)。这应该是你要删除列表基础同步块。

对于打印,另一个答案是正确的,不能保证跨线程的文件写顺序会发生。例如,线程1可能会将8写入打印流,然后线程2会写入11。如果线程2刷新然后线程1刷新,则生成的文件将包含11 ... 8。按此顺序(在它们之间插入可能的其他值取决于刷新的其他内容)。