对于这个简单的同步语句:
public void addName(String name) {
synchronized(this) { // line1
lastName = name;
nameCount++;
}
nameList.add(name);
}两个线程(比如t1和t2 )可以同时调用addName方法,但是一旦得到注释为line1的行,只有一个线程可以继续,这意味着其他线程必须挂起。这意味着即使将nameList放在同步语句之外,也可以保证nameList不会被多个线程冲突。
这是真的吗?如果是,如果在同步语句之前不需要进行任何操作,那么以下方法之间是否有任何区别:
public void addName(String name) {
synchronized(this) { //line1
lastName = name;
nameCount++;
nameList.add(name);
}
}或者:
public synchronized void addName(String name) {
lastName = name;
nameCount++;
nameList.add(name);
}我很清楚
void synchronized add(){
}与以下相同:
void add(){
synchronized(this){
}
}令我困惑的是,在addName示例中,我认为执行顺序可能是这样的:
t1:synchronized steatement
t1:nameList.add
t2:synchronized steatement
t2:nameList.add这意味着synchronized statement和nameList.add之间的其他线程没有执行更改。因此,将nameList.add放入我们的外部同步块中并没有什么不同。
但实际上,执行过程可能类似于@JB的回答:
t1:synchronized steatement
t2:synchronized steatement
t2:nameList.add
t1:nameList.add然后,把nameList放在外部或内部块是很重要的。
发布于 2015-04-12 08:31:07
最后两个片段是等价的,但第一个不是。
在第一个片段中,考虑到列表中添加的内容不是同步块的一部分,两个线程可以并发执行该指令。如果这个列表不是线程安全的,那么它就是一个问题。
即使列表是线程安全的,它也可能是一个问题,因为对状态的各个部分(计数、姓氏和列表)的更改并不是原子性的。因此,其他线程可能会看到姓氏的新值,但不会在列表中找到这个姓氏。
https://stackoverflow.com/questions/29587461
复制相似问题