使用同步方法替代同步代码块是否有优势|Java Debug 笔记

327 阅读2分钟

**本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接 **

问题: 有人可以告诉我用同步方法替代同步代码块有什么优势吗? 最好举个例子

------------------------------以下为回答,按支持票数排序----------------------------------

回答1(支持票数442):
Can anyone tell me the advantage of the synchronized method over the synchronized block with an example? Thanks.

使用同步方法替换同步代码块并没有明显的优势。 也许有一个(但是我并不认为是一个优势)就是你不需要再加上对象引用this。 同步方法:

public synchronized void method() { // blocks "this" from here.... 
    ...
    ...
    ...
} // to here

同步代码块:

public void method() { 
    synchronized( this ) { // blocks "this" from here .... 
        ....
        ....
        ....
    }  // to here...
}

看见了吗?根本没有优势。

但是,块确实比方法具有优势,主要是在灵活性上,因为您可以将另一个对象用作锁,而同步该方法将锁定整个对象。 比较以下两块代码:

// 锁住整个对象
... 
private synchronized void someInputRelatedWork() {
    ... 
}
private synchronized void someOutputRelatedWork() {
    ... 
}
// 使用指定的对象锁
Object inputLock = new Object();
Object outputLock = new Object();

private void someInputRelatedWork() {
    synchronized(inputLock) { 
        ... 
    } 
}
private void someOutputRelatedWork() {
    synchronized(outputLock) { 
        ... 
    }
}

同样,如果扩展方法仍然可以保持同步锁的部分:

 private void method() {
     ... code here
     ... code here
     ... code here
    synchronized( lock ) { 
        ... very few lines of code here
    }
     ... code here
     ... code here
     ... code here
     ... code here
}
回答2(支持票数142):

唯一的不同是同步代码块可以选择指定对象作为锁,然而同步方法只能使用this(或同步类方法使用其对应的类实例)。例如,下面两种语义是等效的:

synchronized void foo() {
  ...
}

void foo() {
    synchronized (this) {
      ...
    }
}

后者更灵活,因为它可以竞争任何对象(通常是成员变量)的关联锁。它也更精细,因为您可以在块之前和之后执行并发代码,但仍可以在该方法内执行。当然,通过将并发代码重构为单独的非同步方法,您也可以轻松使用同步方法。这样使用可以使代码更容易理解。