你可以像这样同步一个ArrayList:
ArrayList<Integer> myList = new ArrayList<Integer>();
synchronized (myList) {
// add, delete, and modify list here is okay
}
我不能使用Collections
实用程序类返回的synchronized ArrayList,所以上面的代码好吗?
答案 0 :(得分:1)
你可以synchronize
任何Java Òbject
和ArrayList
也是Ò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>());