第十一章: 実行性能とスケーラビリティ
1時半就寝、7時45分起床。
うーん、正直この辺りは今はさっと見るだけで良いかな。何より安全なコードを書ける方が大事なので。
チューニング
並行プログラムのチューニングにおいては、推測でチューニングせず、実測でチューニングすること。
アムダールの法則
チューニングする際の指標に使える。
今までの復讐も兼ねて
11章に書かれていたコードを読む。
以前ロックを出来るだけ短く保持すべきだと書いた。必要以上にロックを長く保持したり、そのロックへのリクエストが頻繁にあると実行性能が落ちてしまう。
public class AttributeStore { private final Map<String, String> attributes = new HashMap<String, String>(); public synchronized boolean userLocationMatches(String name, String regex) { String location = attributes.get(name); if (location == null) { return false; } return Pattern.matches(regex, location); } }
これはメソッド全体を同期化しているが、本来同期化が必要なのはMap.getの部分のみ。
public boolean userLocationMatches(String name, String regex) { String location; synchronized (this) { location = attributes.get(name); } if (location == null) { return false; } return Pattern.matches(regex, location); }
Mapへのアクセスを同期化する。
更に、このAttributeStoreが持つステート変数はattributesのみなので、スレッドセーフ性を委譲するテクニックを使うことも出来る。attributesをスレッドセーフなコレクション (ConcurrentHashMap) などにすれば、AttributeStoreのスレッドセーフの義務の全てを委譲出来る。
ふむふむ。最後がやっぱり重要かなぁ。一連のアトミックな操作が必要なものでなかったり、ステート変数が単一の場合はスレッドセーフ性をより堅牢なライブラリに委譲してしまう。