スレッドの落とし穴(2/6 ページ)
Windowsプログラマーでスレッドをいちども使ったことがない人はいないだろう。CPUのマルチコア化によって、ソースコードが上から順に実行という定説がなくなったのは久しい。このdev .NET特集では、知らぬと怖いテクニックを解説する。
元のコードの問題点を改めて追ってみるが、ここからは話が複雑になる。自信のない人は、前節の解答だけを頭に入れておいてほしい。前述したように、挙げたコードでほとんどの場合、用が足りるはずだ。
Lock対象の問題
最初の問題は、マイクロソフト自身が当初間違えていたことによって、多くの人が間違えているようだ。この行を見てほしい。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
C#とVB.NETにおけるlock/SyncLockの対象は、object、つまり参照型なら何でもよいことになっている。型も参照型であるため、文法的にはこれで正しい。また、Visual Studio付属のSDK中のサンプルにもこの使い方が頻発するため、誰が教えなくても何気なくそのまま書いてしまうプログラマーが多い。
しかし、SDKにこの記法のサンプルを入れてしまったことは間違いであったと米Microsoftの社員がBlogに書いている。
問題は、「typeof(A)」がどこからでもアクセスできることによる。例えば別のプログラマーが別のクラスの中で次のように書いたとしよう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
同じ対象オブジェクトを使い、別の目的でlockをかけてしまえば、デッドロックの危険性が高まる。クラス外からも参照可能なオブジェクトを使ってのlockは危険、と覚えておこう。時折見かけるこのコードも同じ理由で危険だ。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
「this」は、もちろんほかのクラスから参照されるので、それ自体をlockしてはいけない。この規則に従って元のコードを直してみよう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
このコードでは、lock用に別の静的変数を確保している。この変数はクラス外からは参照できないため、同じクラス内で間違えない限り、デッドロックの心配がない。
Copyright © ITmedia, Inc. All Rights Reserved.