yohhoyの日記

技術的メモをしていきたい日記

synchronizedは実装詳細である

プログラミング言語Javaにおけるsynchronized修飾されたメソッドでは、synchronizedはインタフェース*1シグネチャ)の一部ではなく、そのメソッドの実装詳細に過ぎない。

メソッドの実装に対する言及となるため、抽象メソッド(interfaceまたはclassのabstruct修飾メソッド)をsynchronized修飾するとコンパイルエラーを引き起こす。Java Language Specification 3rd Ed.(Java SE 5.0)より一部引用。

(snip) A compile-time error occurs if a method declaration that contains the keyword abstract also contains any one of the keywords private, static, final, native, strictfp, or synchronized. (snip)

CHAPTER 8 Classes, 8.4.3 Method Modifiers

Note that a method declared in an interface must not be declared strictfp or native or synchronized, or a compile-time error occurs, because those keywords describe implementation properties rather than interface properties. (snip)

CHAPTER 9 Interfaces, 9.4 Abstract Method Declarations

メソッドをsynchronized修飾することとスレッド安全であることは同義ではない。スレッド安全性については別途ドキュメンテーションが必要となる。

Javadocツールは、修飾子publicprotectedprivateabstractfinalstatictransient、およびvolatileを組み込むことができますが、synchronizednativeを組み込むことができません。これら後者の2つの修飾子は、実装の詳細と見なされているため、API仕様には含まれません。

APIでは、並行性のセマンティクスについて、キーワードsynchronizedに依存するのではなく、コメントによる主説明としてドキュメント化する必要があります。たとえば、「1つのEnumerationを複数のスレッドから並行して使用することはできない」などのコメントを記述します。ドキュメントには、これらのセマンティクスを実現する方法を記述するべきではありません。たとえば、Hashtableはスレッドに対して安全である必要がありますが、「エクスポートされるすべてのメソッドを同期化すればそれを実現できる」のようには指定する根拠はありません。バケットレベルで内部的に同期化する権利を残しておく必要があります。そうすれば、より高度な並行性が提供されます。

javadoc - Java API ドキュメントジェネレータ

おまけ:Eclipseでは「親クラスのsynchronizedメソッドをオーバーライドしているのにsynchronized修飾が無い」警告を出せるらしい。http://stackoverflow.com/questions/15374521#15374704参照。

関連URL

*1:ここではJava言語要素のinterfaceではなく、一般名詞としてのインタフェースを意図している。