Java ArrayList,检查两个线程上的大小

Java ArrayList,检查两个线程上的大小,java,multithreading,arraylist,copyonwritearraylist,Java,Multithreading,Arraylist,Copyonwritearraylist,我有一份清单: ArrayList=新建ArrayList() 在第一个线程中,我添加了元素(速度很快-30/秒) 在第二个线程上,我读取它的大小并打印到文件中 第一个线程: synchronized(list){ list.add(PlayerPosition); } synchronized(list){ if(list.size()>0) out.print(list.size() + " "); } 第二个线程: synchronized(list){

我有一份清单:

ArrayList=新建ArrayList()

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

第一个线程:

synchronized(list){
    list.add(PlayerPosition);
}
synchronized(list){
if(list.size()>0)
    out.print(list.size() + " ");
}
第二个线程:

synchronized(list){
    list.add(PlayerPosition);
}
synchronized(list){
if(list.size()>0)
    out.print(list.size() + " ");
}
它是文件的输出,只是一部分: 1 1 3 3 5 4 6 7 9 11 8 9 12 10 14 16

这是错误的,因为它只会增加。可能有11个,但不可能有11个

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

我有一个问题:这是否可能,它的行为是这样的? 否则的话,代码中的某个地方是我的错

是的,我试过使用CopyOnWriteArrayList-同样的东西。
谢谢

可能未按您期望的顺序执行
打印。将第二个线程的代码更改为以下代码:

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

您的
OutputStream
正在向终端(或文件或其他内容)写入字符。在不同步
out
和刷新的情况下,当线程2通知
OutputStream
打印时,可能是上一次打印尚未完成。同步和刷新迫使线程2等待所有字符实际写入终端后再继续。

您可以通过以下几种方法改进代码。首先,您不必自己实现同步原语。Java已经内置了SynchronizedList。请参见
Collections.synchronizedList(列表)
。这将使您能够删除列表块


对于打印,另一个答案是正确的,即不能保证跨线程的文件写入将按顺序进行。例如,线程1可能向打印流写入
8
,然后线程2写入
11
。如果线程2刷新,那么线程1刷新,结果文件将包含
11
8
。按此顺序(根据刷新的内容,可能会在它们之间插入其他值)。

可能只是
输出。打印问题