私が作成しているアプリケーションでは、不変である可能性が高い多くの基本型を作成する必要があります。しかし、可変型と不変型が並列アプリケーションでどのように比較されるのか疑問に思っています。
変更可能なオブジェクトでロックを使用できますよね? 並列アプリケーションで不変型に使用される他の手法と比べてどうですか?
少なくとも、不変型のロックを使用することから離れていますよね?
私が作成しているアプリケーションでは、不変である可能性が高い多くの基本型を作成する必要があります。しかし、可変型と不変型が並列アプリケーションでどのように比較されるのか疑問に思っています。
変更可能なオブジェクトでロックを使用できますよね? 並列アプリケーションで不変型に使用される他の手法と比べてどうですか?
少なくとも、不変型のロックを使用することから離れていますよね?
種類
スレッド
明示的なロックを使用する必要がある場合は、詳細に文書化してください。特に、オブジェクトをロックする順序に関しては。Foo オブジェクトが常に Bar オブジェクトの前にロックされ、Foo(key 100) が常に Foo(key = 200) の前にロックされることがわかっている場合、デッドロックは発生しません。
並列化可能なアプリケーションを作成するための鍵は、変更可能な共有状態を避けることです。スレッド間で変更可能な状態を共有するには、通常、何らかの形式のロックを必要とする同期が必要です。不変型を使用すると、それらのオブジェクトの状態を変更できないようにすることで、誤って状態を共有しないようにすることができます。ただし、これは特効薬ではなく、単なる設計上の選択です。並列化しようとしているアルゴリズムが共有状態を必要とする場合、何らかの同期を作成する必要があります。
可変性はロックに影響しません。
可変型を使用すると、Write-After-Read または Write-After-Write エラーにさらされます。これらは、他のスレッドが同時に値を読み取ったり更新したりしているときに、値を更新することに関連する同期エラーです。
同期エラーを防ぐには、何らかの形式のロック メカニズムを使用する必要があります。明示的なロックを使用する場合は、ロックを取得する順序に十分注意する必要があります。注意しないと、デッドロックが発生する可能性があります。例: スレッド A がロック X を取得し、次にスレッド B がロック Y を取得します。その後、スレッド A がロック Y を要求し、スレッド B がロック X を要求します。これにより、両方のスレッドが決して解放されないロックを無期限に待機します。
ロックに関する 2 つの優れた経験則:
作成後にオブジェクトに書き込みを行わない場合は、アクセスする前にオブジェクトをロックする必要はありません。したがって、不変オブジェクトをロックする必要はありません。
可能な場合は不変型を使用してください。必要な場合は可変型を使用します(シリアル化など)。
すべての並列化にSystem.Threading.Tasksを使用します-asyncおよびawaitキーワードが追加されると、タスクはC#5の言語で組み込まれることもあります。
C#で可変/不変タイプに関する記事を書きました:http://rickyhelgesson.wordpress.com/2012/07/17/mutable-or-immutable-in-a-parallel-world/