首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java同步锁

Java同步锁
EN

Stack Overflow用户
提问于 2011-03-27 18:34:48
回答 6查看 429关注 0票数 4

当我们说我们使用synchronized关键字锁定一个对象时,这是否意味着我们正在获取整个对象上的锁,还是只在块中存在的代码上获得锁?

在下面的示例中,listOne.add是同步的,这是否意味着如果另一个线程访问listOne.get,它将被阻塞,直到第一个线程离开这个块?当第一线程仍在synchronized块中时,如果第二个线程访问同一对象的实例变量上的listTwo.getlistTwo.add方法,该怎么办?

代码语言:javascript
复制
List<String> listONe = new ArrayList<String>();
List<String> listTwo = new ArrayList<String>();

/* ... ... ... */

synchronized(this) {
    listOne.add(something);
}
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-03-27 18:53:49

给定以下方法:

代码语言:javascript
复制
  public void a(String s) {
    synchronized(this) {
      listOne.add(s);
    }
  }

  public void b(String s) {
    synchronized(this) {
      listTwo.add(s);
    }
  }

  public void c(String s) {
      listOne.add(s);
  }

  public void d(String s) {
      synchronized(listOne) {
        listOne.add(s);
      }
  }

您不能同时调用a和b,因为它们被锁定在同一个锁上。但是,您可以同时调用a和c(显然是使用多个线程),因为它们不是锁定在同一个锁上。这可能会给listOne带来麻烦。

你也可以同时调用a和d,因为在这个上下文中d和c没有什么不同,它不使用相同的锁。

重要的是,您始终使用相同的锁来锁定listOne,并且不允许在没有锁的情况下访问它。如果listOne和listTwo在某种程度上是相关的,并且有时需要同时/原子地更新,那么你需要一个锁才能访问它们。否则,两个单独的锁可能更好。

当然,如果您需要的只是一个并发列表,那么您可能会使用相对较新的java.util.concurrent类:)

票数 6
EN

Stack Overflow用户

发布于 2011-03-27 18:40:55

锁位于包含在synchronized块中的对象实例上。

但是要小心!这个对象是的,而不是本质上锁定的,不能被其他线程访问。只有执行相同synchronized(obj)的线程才会等待该锁,在您的示例中obj是this,但在其他线程中也可以是一个变量引用。

因此,不执行任何同步语句的线程可以访问“锁定”对象的任何和所有变量,您可能会遇到竞争条件。

票数 6
EN

Stack Overflow用户

发布于 2011-03-27 18:37:53

如果您在同一实例上有一个synchronized块,则其他线程仅会阻塞。因此,列表本身上的任何操作都不会阻塞。

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

https://stackoverflow.com/questions/5448681

复制
相关文章

相似问题

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