同步ArrayList

时间:2016-10-05 17:01:46

标签: java multithreading concurrency thread-safety

你可以像这样同步一个ArrayList:

ArrayList<Integer> myList = new ArrayList<Integer>();

synchronized (myList) {
    // add, delete, and modify list here is okay
}

我不能使用Collections实用程序类返回的synchronized ArrayList,所以上面的代码好吗?

2 个答案:

答案 0 :(得分:1)

你可以synchronize任何Java ÒbjectArrayList也是Òbject,所以它是一个有效的语法,但是因为你已用注释代码编写了,

  

//在这里添加,删除和修改列表是可以的

我想,功能上这不是你想要实现的。我想,当多个线程尝试访问该段代码时,您希望以同步方式添加,删除和修改ArrayList

如果您执行synchronized (myList),则只是将列表用作锁定而不是其他任何内容,即这不会使myList线程上的操作安全。

而不是那样,你应该synchronized (this) this,其中myList是包含您列出的示例代码的类的实例,然后在该块中对synchronized (myList)执行操作,如添加元素,删除元素等。

如果您正在寻找Collections.synchronizedList的替换,那么

new ArrayList<Integer>()在功能上是不正确的,因为每个线程都会锁定新对象,因为您为每个新线程执行myList。您需要为每个线程同步相同对象

此外,如果 if err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error { if err != nil { return check(err) } var link string if info.Mode()&os.ModeSymlink == os.ModeSymlink { if link, err = os.Readlink(path); err != nil { return check(err) } } header, err := tar.FileInfoHeader(info, link) if err != nil { return check(err) } header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, directory)) if err = tw.WriteHeader(header); err != nil { return check(err) } if !info.Mode().IsRegular() { //nothing more to do for non-regular return nil } fh, err := os.Open(path) if err != nil { return check(err) } defer fh.Close() if _, err = io.CopyBuffer(tw, fh, buf); err != nil { return check(err) } return nil }) 不是多个线程共享的字段,则根本不需要对列表进行同步访问,因为您每次都在创建新的ÀrrayList`,因此每个调用者线程都在新列表上工作。

答案 1 :(得分:0)

您无需付出努力。

您可以使用synchronizedList

例如:

List myList = Collections.synchronizedList(new ArrayList<Integer>());