在我的代码中,我在同一资源上另一个同步块内的资源set
上使用了一个synchronized块。到目前为止,这并没有给我带来任何问题,但我很好奇:如果有的话后果是什么?这些同步块会相互冲突吗?
Set<myClass> set = Collections.synchronizedSet(new HashSet<myClass>());
synchronized(set) {
set.add(new myClass());
...
writeSetContentsToFile();
}
public synchronized void writeSetContentsToFile() {
synchronized(set) {
...
}
}
该组由其他线程连续访问和更改。我同步writeSetContentsToFile()
,因此文件资源不会有任何冲突,同样,writeSetContentsToFile()
内有一个同步块,以确保迭代时不会对该集进行任何更改
答案 0 :(得分:1)
到目前为止,这并没有给我带来任何问题,但我很好奇:如果有的话会有什么后果?
在某种程度上,你回答了自己的问题,但这有点令人困惑。如果可以,最好简化代码。您需要查看其余代码以确定是否可行。
答案 1 :(得分:1)
这里有两个锁,this
上有一个,set
上有一个锁。如果两个线程以不同的顺序锁定它们,那就是BANG。僵局。您没有显示所有代码,因此可能无法实现,但是当有人更改类以添加新方法时呢?
正如Peter Lawrey所说,你应该尝试简化这段代码。
答案 2 :(得分:1)
如果您的操作以
表示synchronized(set) {
set.add(new myClass());
...
writeSetContentsToFile();
}
是原子的,将其封装在单独的类中,比如ThreadSafeFileStorableSet
,在专用方法下,比如synchronized writeContentsToFile()
。
例如:
class ThreadSafeFileStorableSet {
private final Set set;
ThreadSafeFileStorableSet(Set set) {
this.set = set;
}
synchronized void writeSetContentsToFile() {
//
}
synchronized void addElements(Object[] elems) {
//
}
private void doWrite() {
// use instance set
}
}
使ThreadSafeFileStorableSet
类synchronized
的所有其他非私有方法也是如此,因此所有操作都将彼此原子化。那么你不需要在这个课程中使用synchronized (set)
个片段。
这将简化您的代码,但可能会使并发级别更糟。但是我没有足够的信息来告诉您阅读代码会变得多糟糕。