当方法仅在同步块冗余中调用时,是否使方法同步?操作系统级别会发生什么?

时间:2013-02-12 01:41:03

标签: java multithreading synchronization

假设你有一个只在同步块中调用的方法foo()

制作方法

synchronized void foo() {..}

相对

void foo() {..}

多余或不好的做法,还是让方法的意图更清晰?在方法签名上使用synchronized关键字会使程序变慢吗?我想知道更好的做法是什么,或者我是否遗漏了大局的一部分。

感谢。

3 个答案:

答案 0 :(得分:1)

通常,这意味着foo()本身不是原子动作,它可能不保留不变量,它只是更宏大的同步方案的一部分。

然后它应该声明synchronized,否则读者可能会得到错误的想法;而且它也有点慢。

相反,你可以

void foo()
{
    assert Thread.holdsLock(this);
    ...
}

它有两个目的

  1. 记录此方法只能在外部synchonized(this)块中调用
  2. 在运行时检查该需求(我将为所有非生产运行启用assersion)

答案 1 :(得分:1)

这并不是多余的,在实践中,同步你已经拥有的锁定是相当普遍的。

在线程安全和不线程之间明确定义边界的API更容易使用,最佳边界可能是在类级别。因此,如果该类的其余部分是线程安全的,并且foo()方法将是线程安全的,如果已同步,那么您也可以这样做,并在您的类文档中记下它。如果同步foo()将为您提供具有混合线程安全和非线程安全调用的API,那么这将导致以后混淆。

关于性能我怀疑这是一个问题(无争议的锁应该具有最小的开销)。让代码工作,然后看看你是否需要加快速度。

答案 2 :(得分:0)

我想你的foo()方法在A类中,而调用者代码(在同步块内调用它)在另一个B类中。

我的建议不是制作A synchronized的方法,因为在单线程程序中,调用会系统地变慢。

如您所指出的,最好通过使用synchronized块来使客户端类(例如B)执行同步作业。

总之,我的建议是不要声明方法是同步的,因为它更灵活:您可以使用具有外部同步块的类来创建线程安全的程序,并且还可以生成快速的单线程应用程序。您还可以警告您的用户您的A类不是线程安全的。