ArrayList,检查 2 个线程的大小
ArrayList, checking size on 2 threads
我有一个列表:
ArrayList 列表 = 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.
我的程序很大,但这些只是这个列表中出现的几个(我已经删除了一半的代码来调试它)。整个app没有list.remove()
等
我有一个问题:这可能吗,它是这样的吗?
其他原因 - 这是我在代码中的某个地方的错。
是的,我已经尝试使用 CopyOnWriteArrayList - 同样的事情。
谢谢!
可能 print
未按您期望的顺序执行。将第二个线程的代码改成如下:
synchronized(list){
if (list.size() > 0) {
synchronized (out) {
out.print(list.size() + " ");
out.flush();
}
}
}
您的 OutputStream
正在将字符写入终端(或文件或其他内容)。如果不在 out
上同步并刷新,当线程 2 告诉 OutputStream
打印时,可能之前的打印尚未完成。同步和刷新强制线程 2 等到所有字符都实际写入终端后再继续。
您可以通过多种方式改进上述代码。首先,您不必自己实现同步原语。 Java 已经内置了 SynchronizedList。参见 Collections.synchronizedList(list)
。这应该所有你删除列表基地同步块。
对于打印,另一个答案是正确的,不能保证文件跨线程写入会顺序发生。例如,线程 1 可能将 8
写入打印流,然后线程 2 写入 11
。如果线程 2 刷新然后线程 1 刷新,生成的文件将包含 11
...8
。按照这个顺序(根据刷新的内容,可能在它们之间插入其他值)。
我有一个列表:
ArrayList 列表 = 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.
我的程序很大,但这些只是这个列表中出现的几个(我已经删除了一半的代码来调试它)。整个app没有list.remove()
等
我有一个问题:这可能吗,它是这样的吗? 其他原因 - 这是我在代码中的某个地方的错。
是的,我已经尝试使用 CopyOnWriteArrayList - 同样的事情。 谢谢!
可能 print
未按您期望的顺序执行。将第二个线程的代码改成如下:
synchronized(list){
if (list.size() > 0) {
synchronized (out) {
out.print(list.size() + " ");
out.flush();
}
}
}
您的 OutputStream
正在将字符写入终端(或文件或其他内容)。如果不在 out
上同步并刷新,当线程 2 告诉 OutputStream
打印时,可能之前的打印尚未完成。同步和刷新强制线程 2 等到所有字符都实际写入终端后再继续。
您可以通过多种方式改进上述代码。首先,您不必自己实现同步原语。 Java 已经内置了 SynchronizedList。参见 Collections.synchronizedList(list)
。这应该所有你删除列表基地同步块。
对于打印,另一个答案是正确的,不能保证文件跨线程写入会顺序发生。例如,线程 1 可能将 8
写入打印流,然后线程 2 写入 11
。如果线程 2 刷新然后线程 1 刷新,生成的文件将包含 11
...8
。按照这个顺序(根据刷新的内容,可能在它们之间插入其他值)。