始めます!今日から「並行プログラミングのアート」を読み始めます。この本は先輩のおすすめで知りました。並行プログラミングについてより深く理解することができるでしょう。実際、プロジェクトで既に並行の問題に遭遇していますが、まだ体系的に学んでいませんでした。今は忙しいですが、すぐに補いたいと思います。
PS: ロックに関連する画像を特別に選びました。また、誠実さと金の鍵を象徴しています🔒
一、コンテキストスイッチ#
シングルコアプロセッサでも複数のスレッドでコードを実行することができます。CPU は各スレッドに CPU タイムスライス(通常は数十ミリ秒)を割り当てることで、このメカニズムを実現しています。
現在のタスクは 1 つのタイムスライスを実行した後、次のタスクに切り替わります。切り替える前に、前のタスクの状態を保存しておき、次回このタスクに切り替える際に、このタスクの状態を再度読み込むことができます。タスクの保存から読み込みまでのプロセスは、コンテキストスイッチと呼ばれます。
コンテキストスイッチを減らす方法は?
- ロックフリーな並行プログラミング。複数のスレッドがロックを競合すると、コンテキストスイッチが発生することがあります。データの ID をモジュロ演算子で分割し、異なるスレッドが異なるセグメントのデータを処理するなど、ロックを回避する方法があります。
- CAS アルゴリズム:Java の Atomic パッケージは CAS アルゴリズムを使用してデータを更新するため、ロックは必要ありません。
- 最小限のスレッドを使用し、不要なスレッドを作成しないようにする。
- 単一スレッドで複数のタスクのスケジューリングを実現し、単一スレッドで複数のタスクの切り替えを維持する。
二、デッドロック#
デッドロックを避けるためのいくつかの一般的な方法:
- 1 つのスレッドが複数のロックを取得しないようにする。
- 1 つのスレッドがロック内で複数のリソースを同時に占有しないようにし、各ロックが 1 つのリソースだけを占有するようにする。
- タイムアウトロックを使用し、lock.tryLock (timeout) を内部ロックメカニズムの代わりに使用する。
- データベースロックの場合、ロックとアンロックは同じデータベース接続内で行う必要があります。そうでないと、アンロックに失敗する可能性があります。
三、リソース制約の課題#
問題:ある一部の直列コードを並行に実行すると、リソースの制約により、依然として直列実行され、プログラムの実行が速くなるどころか、コンテキストスイッチとリソーススケジューリングの時間が増えてしまいます。
解決策:
ハードウェアリソースの制約に対しては、クラスターを構築して並列にプログラムを実行します。異なるマシンが異なるデータを処理するようにします。
ソフトウェアリソースの制約に対しては、リソースプールを使用してリソースを再利用することを検討します。
異なるリソース制約に応じてプログラムの並行度を調整します。