質問の最初のシナリオに興味がある人のために、ロックを処理するときにスレッドのプリエンプションをテストするために行った実験を次に示します。
object resourselock = new object();
public void Test()
{
Thread lowestThread = new Thread(new ThreadStart(Low));
lowestThread.Priority = ThreadPriority.Lowest;
Thread highestThread = new Thread(new ThreadStart(High));
highestThread.Priority = ThreadPriority.Highest;
lowestThread.Start();
Thread.Sleep(1000); //makes sure that the lowest priority thread starts first
highestThread.Start();
}
public void Low()
{
Console.WriteLine("Low priority task executed");
lock (resourselock)
{
Console.WriteLine("Low priority task will never release the lock!");
while (true) ; //infinite empty statement!
}
}
public void High()
{
System.Console.WriteLine("High priority task executed");
lock (resourselock)
{
System.Console.WriteLine("High priority task got the lock!"); //this will never be reached!
}
}
以下は、プログラムの出力です。
実行された優先度の低いタスク
優先度の低いタスクは決してロックを解除しません!
実行された優先度の高いタスク
優先度の高いタスクを実行するには、優先度の低いタスクがすでに取得しているリソースロックを取得する必要がありますが、優先度の高いタスクを実行しただけで、実行できないことがわかりました!! したがって、タスクの実行にリソースが必要な場合に不要なコンテキストの切り替えを防ぐために、コンパイラによって行われる最適化はまったく行われません。