web-dev-qa-db-ja.com

同期(this)メソッドと同期メソッドの違いは何ですか

これらの2つのサンプルコードがあるとしましょう:

public synchronized void getSomething(){
     this.hello = "hello World";
}

そしてこれ

public void getSomething(){
   synchronized(this){
     this.hello = "hello World";
   }
}

だから誰かが今の違いは何ですか?

29
Tarik

2つの異なる方法は機能的に同等です。 may非常に小さいパフォーマンス違い:

バイトコードレベルでは、同期メソッドは、メソッドのアクセスフラグに設定されたビットとして同期の必要性をアドバタイズします。 JVMはこのビットフラグを探し、適切に同期します。

同期ブロックは、クラスファイルのメソッド定義に格納されている一連のバイトコード操作を通じて同期を実装します。

したがって、同期されたメソッドmightは、実行速度がわずかに速くなり、バイトコードに関して占有するスペースが少なくなる可能性があります。

この場合も、仕様により、この2つは機能的に同一です。

パフォーマンスの違いはごくわずかであり、コードスタイルのガイドラインが勝つはずだと思います。一部のコンパイラは、ブロックを最適化してアクセスフラグにすることもできます。そして、JITはパフォーマンスの違いを取り除くかもしれません。

38
Mike Clark

この記事のこの部分をチェックしてください:

http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/#4

機能的には一致しているが(メソッドの同期はインスタンスオブジェクトをロックするか、静的メソッドの場合はメソッドが存在するクラスのクラスオブジェクトをロックする)、メソッドの同期はバイトコードで同期するよりもはるかに最適であると説明しています。 (同期されたブロックステートメントと同様に)、JVMレベルで同期します。

19
Carrotman42

1つの違いは、同期されるコードの粒度です。最初の例では、基本的にメソッド全体をロックしていますが、2番目の例では、メソッドの一部のみがロックされます。 2番目のアプローチは、本体を完全に同期する必要がない長いメソッドに適しています。必要な場合にのみロックし、他のスレッドのロックをできるだけ早く解除するのが最善です。

9
D.C.