首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步语句-同步方法和同步语句是否等效?

同步语句-同步方法和同步语句是否等效?
EN

Stack Overflow用户
提问于 2015-04-12 08:26:44
回答 1查看 168关注 0票数 3

对于这个简单的同步语句:

代码语言:javascript
复制
public void addName(String name) {
    synchronized(this) { // line1
        lastName = name;
        nameCount++;
    }
    nameList.add(name);
}

两个线程(比如t1t2 )可以同时调用addName方法,但是一旦得到注释为line1的行,只有一个线程可以继续,这意味着其他线程必须挂起。这意味着即使将nameList放在同步语句之外,也可以保证nameList不会被多个线程冲突。

这是真的吗?如果是,如果在同步语句之前不需要进行任何操作,那么以下方法之间是否有任何区别:

代码语言:javascript
复制
public void addName(String name) {
    synchronized(this) {  //line1
        lastName = name;
        nameCount++;

        nameList.add(name);
    }
}

或者:

代码语言:javascript
复制
public synchronized void addName(String name) {
        lastName = name;
        nameCount++;
        nameList.add(name);
}

我很清楚

代码语言:javascript
复制
void synchronized add(){

}

与以下相同:

代码语言:javascript
复制
void add(){
  synchronized(this){

  }
}

令我困惑的是,在addName示例中,我认为执行顺序可能是这样的:

代码语言:javascript
复制
t1:synchronized steatement
t1:nameList.add
t2:synchronized steatement
t2:nameList.add

这意味着synchronized statementnameList.add之间的其他线程没有执行更改。因此,将nameList.add放入我们的外部同步块中并没有什么不同。

但实际上,执行过程可能类似于@JB的回答:

代码语言:javascript
复制
t1:synchronized steatement
t2:synchronized steatement

t2:nameList.add
t1:nameList.add

然后,把nameList放在外部或内部块是很重要的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-12 08:31:07

最后两个片段是等价的,但第一个不是。

在第一个片段中,考虑到列表中添加的内容不是同步块的一部分,两个线程可以并发执行该指令。如果这个列表不是线程安全的,那么它就是一个问题。

即使列表是线程安全的,它也可能是一个问题,因为对状态的各个部分(计数、姓氏和列表)的更改并不是原子性的。因此,其他线程可能会看到姓氏的新值,但不会在列表中找到这个姓氏。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29587461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档