tôi đã tự hỏi điều tương tự khi cố gắng kiểm toán mã của tôi cho khóa chính xác. Tôi đã đưa ra một phương pháp bằng cách sử dụng một chuỗi thứ hai. Nếu khóa có sẵn cho chuỗi cuộc gọi, nhưng không có sẵn cho chuỗi thứ hai, nó phải được giữ bởi chuỗi đầu tiên.
/// <summary>
/// Utiltity for checking if a lock has already been acquired.
/// WARNING: This test isn't actually thread-safe,
/// it's only really useful for unit tests
/// </summary>
private static bool ObjectIsAlreadyLockedByThisThread(object lockObject)
{
if (!Monitor.TryEnter(lockObject))
{
// another thread has the lock
return false;
}
Monitor.Exit(lockObject);
bool? LockAvailable = null;
var T = new Thread(() =>
{
if (Monitor.TryEnter(lockObject))
{
LockAvailable = true;
Monitor.Exit(lockObject);
}
else
{
LockAvailable = false;
}
});
T.Start();
T.Join();
return !LockAvailable.Value;
}
// Tests:
public static void TestLockedByThisThread()
{
object MyLock = new object();
lock (MyLock)
{
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
Debug.WriteLine(WasLocked); // prints "True"
}
}
public static void TestLockedByOtherThread()
{
object MyLock = new object();
var T = new Thread(() =>
{
lock (MyLock)
{
Thread.Sleep(TimeSpan.FromSeconds(2));
}
});
T.Start();
Thread.Sleep(TimeSpan.FromSeconds(1));
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
T.Join();
Debug.WriteLine(WasLocked); // prints "False"
}
public static void TestNotLocked()
{
object MyLock = new object();
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
Debug.WriteLine(WasLocked); // prints "False"
}
Tôi sẽ không sử dụng mã này trong mã sản xuất - có điều kiện chạy đua có thể phát nổ. Tuy nhiên, các bài kiểm tra đơn vị của tôi chủ yếu là các luồng đơn, vì vậy điều này rất hữu ích.
+1, chính xác. Trả lời câu hỏi này về trạng thái quá khứ của khóa chỉ có thể khiến bạn đưa ra quyết định không chính xác. – JaredPar
Tôi khóa mọi thứ để tôi có thể xem chúng có đang được sử dụng hay không. ví dụ. Vì vậy, hai chủ đề không đập vỡ các tài nguyên được chia sẻ giống nhau. Tôi muốn xem liệu công việc đó có đang được thực hiện hay không. Tôi có thể làm điều tương tự với một giá trị IsBeingUsed nhưng đối tượng cho khóa đã tồn tại và các khóa hoạt động theo cùng một cách, ngoại trừ việc có thể kiểm tra xem chúng có bị khóa không khi đặt giá trị bị khóa. – QueueHammer
Khi bạn kiểm tra IsBeingUsed, luồng có thể đã dừng công việc hữu ích nhưng một chuyển đổi ngữ cảnh có thể đã xảy ra trước khi IsBeingUsed được cập nhật. –