Java 两个线程使用两个列表还是一个同步列表更好?

Java 两个线程使用两个列表还是一个同步列表更好?,java,multithreading,synchronized,Java,Multithreading,Synchronized,如果线程#1迭代列表并使用数据渲染二维图形,然后线程#2删除项目、添加项目,但主要更改列表中项目的值,那么哪个选项更好/更有效 备选案文1: List<Object> list1 = new ArrayList<Object>(); List<Object> list2 = new ArrayList<Object>(); // Thread 2 ArrayList<Object> newData = new ArrayList&l

如果线程#1迭代列表并使用数据渲染二维图形,然后线程#2删除项目、添加项目,但主要更改列表中项目的值,那么哪个选项更好/更有效

备选案文1:

List<Object> list1 = new ArrayList<Object>();
List<Object> list2 = new ArrayList<Object>();

// Thread 2

ArrayList<Object> newData = new ArrayList<Object>();
newData.add(new Object());

list2 = newData;


// Thread 1

list1 = list2;

for (Object o : list1) {
// use data to render
}
List list1=new ArrayList();
List list2=新的ArrayList();
//线程2
ArrayList newData=新ArrayList();
添加(新对象());
list2=新数据;
//线程1
list1=list2;
for(对象o:list1){
//使用数据渲染
}
备选案文2:

List<Object> list = Collections.synchronizedList(new ArrayList<Object>());

// Thread 2

synchronized(list) {
// add, remove, change values
}

// Thread 1

synchronized(list) {
    for (Object o : list) {
    // use data to render
    }
}
List List=Collections.synchronizedList(新的ArrayList());
//线程2
已同步(列表){
//添加、删除、更改值
}
//线程1
已同步(列表){
用于(对象o:列表){
//使用数据渲染
}
}

我对它的工作原理知之甚少,但我担心在第二个选项中,线程1可能会尝试迭代列表,它被锁定,因此线程1运行缓慢,这是可见的,因为它正在渲染。非常感谢您的帮助

选项2

因为,如果不同步它,将引发并发读/写异常

无论哪种方式,如果有多个线程访问
通用集合
,则必须锁定读/写操作。否则,您可能会遇到异常

基本集合读/写规则:

最终并发读取,但1用于修改集合

选项1将不起作用。 在您看来,您已经创建了2个列表,但此行不会将列表1复制到列表2,而是会将指针更改为指向同一数组上的点。 如果您想将list1复制到list2中,它将强制您在list1上迭代,您将得到并发读写异常


因此,选项2更好。

我知道我不是在创建深度克隆,list2不断地被设置为一个新列表,因此list1上次设置为的列表将被除list1之外的所有人删除,不是吗?我不确定“除list1之外的所有人都将删除”是什么意思,但您需要记住,像列表这样的对象(不同于前置类型)只会在执行类似list1=list2的操作时更改它们指向的对象。这意味着现在列表1和列表2指向内存堆中的同一个位置,列表1上的任何更改都将发生在列表2上,因为它们实际上是同一个对象。如果您使用两个列表,您的第二个线程将错过更新,或者至少不清楚它们如何等效于一个列表。使用单个同步列表或同步,但这也不够:如果迭代列表,则必须在循环外部对其进行同步。