首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Java临界区中,我应该在什么地方进行同步?

在Java临界区中,我应该在什么地方进行同步?
EN

Stack Overflow用户
提问于 2009-01-06 11:31:02
回答 5查看 47.2K关注 0票数 75

在Java中,在代码中声明临界区的惯用方法如下:

代码语言:javascript
复制
private void doSomething() {
  // thread-safe code
  synchronized(this) {
    // thread-unsafe code
  }
  // thread-safe code
}

几乎所有的块在this上都是同步的,但是这有什么特殊的原因吗?还有其他的可能性吗?关于在哪个对象上进行同步有什么最佳实践吗?(例如Object的私有实例?)

EN

回答 5

Stack Overflow用户

发布于 2009-01-06 11:35:59

我尽量避免在this上进行同步,因为这将允许所有引用该对象的外部人员阻止我的同步。相反,我创建了一个本地同步对象:

代码语言:javascript
复制
public class Foo {
    private final Object syncObject = new Object();
    …
}

现在我可以使用这个对象进行同步,而不用担心任何人“偷走”锁。

票数 45
EN

Stack Overflow用户

发布于 2009-01-06 14:41:41

我要强调的是,在Java语言中也有ReadWriteLocks可用,它的名称是java.util.concurrent.locks.ReadWriteLock。

在我的大多数使用中,我将我的锁分离为“用于读取”和“用于更新”。如果你简单地使用一个同步的关键字,所有对同一个方法/代码块的读取都将被“排队”。一次只有一个线程可以访问该块。

在大多数情况下,如果你只是在做阅读,你永远不需要担心并发问题。当你在写的时候,你会担心并发更新(导致数据丢失),或者在写的时候会读(部分更新),这是你必须要担心的。

因此,在多线程编程期间,读/写锁对我来说更有意义。

票数 6
EN

Stack Overflow用户

发布于 2009-01-06 12:26:54

Java中的同步通常涉及对同一实例上的操作进行同步。由于this是一个共享引用,在类中的不同实例方法(或部分)之间自动可用,因此在this上进行同步是非常惯用的。

使用另一个专门用于锁定的引用,例如,通过声明和初始化私有字段Object lock = new Object(),这是我从未需要或使用过的东西。我认为只有当你需要对一个对象中两个或更多非同步资源进行外部同步时,它才有用,尽管我总是试图将这种情况重构为一种更简单的形式。

无论如何,隐式(同步方法)或显式synchronized(this)被大量使用,在Java库中也是如此。这是一个很好的习惯用法,如果适用,应该始终是您的首选。

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

https://stackoverflow.com/questions/416183

复制
相关文章

相似问题

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