2

如果您有线程 #1 迭代列表并使用数据渲染 2d 图形,然后线程 #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
}

选项 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
    }
}

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

4

2 回答 2

1

选项 2

因为,如果你不同步它,就会Concurrent Read/Write Exception抛出。

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

基本集合读/写规则:

Ultimate Concurrent Read But 1 用于修改集合

于 2020-02-04T03:31:19.757 回答
0

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

所以Option2更好。

于 2020-02-04T03:39:12.367 回答