造成死锁
本文关键字:死锁 | 更新日期: 2023-09-27 18:11:43
我有一些代码,看起来像下面。这会造成死锁吗?
private readonly object objectLock = new object();
public void MethodA()
{
lock(objectLock)
{
MethodB();
}
}
public void MethodB()
{
lock(objectLock)
{
//do something
}
}
UPDATE:有2个线程在运行
没有-但这将是:
private readonly object objectLockA = new object();
private readonly object objectLockB = new object();
public void MethodA()
{
lock(objectLockA)
{
lock(objectLockB)
{
//...
}
}
}
public void MethodB()
{
lock(objectLockB)
{
lock(objectLockA)
{
//do something
}
}
}
如果你并行调用两个方法(从2个不同的线程),那么你会得到一个死锁…
不,这不是死锁。相同的线程锁定在相同的同步对象上。线程可以使用嵌套锁。它只需要释放它等于no。次。
不,您需要两个锁对象来启用死锁。
如果这是唯一涉及的互斥,它不是。同一个线程可以多次锁定同一个互斥锁,只要它解锁的次数相等。
调用MethodA
在同一线程上产生以下操作序列:
- 锁定
objectLock
. - 呼叫
MethodB
. - 锁定
objectLock
. - 解锁
objectLock
. - 退出
MethodB
. - 解锁
objectLock
.
因此,objectLock
被锁定两次,解锁两次,但没有死锁:
- 如果另一个线程试图调用
- 如果调用
MethodB
,同样会发生。 - 如果第一个线程调用
MethodB
,然后其他线程调用MethodA
,再次发生"正常"阻塞,但不会发生死锁。
MethodA
,它只会阻塞第一个锁,但不会死锁。如果复制粘贴以下行,编译并运行,看到"never called"没有在控制台中打印。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace deadlocktest
{
class Program
{
static object object1 = new object();
static object object2 = new object();
public static void FunctionOne()
{
lock (object1)
{
Console.WriteLine("FunctionOne called 1");
Thread.Sleep(1000);
lock (object2)
{
Console.WriteLine("FunctionOne called 2, never called");
}
}
}
public static void FunctionTwo()
{
lock (object2)
{
Console.WriteLine("FunctionTwo called 1");
Thread.Sleep(1000);
lock (object1)
{
Console.WriteLine("FunctionTwo called 2, never called");
}
}
}
static void Main(string[] args)
{
Thread thread1 = new Thread(FunctionOne);
Thread thread2 = new Thread(FunctionTwo);
thread1.Start();
thread2.Start();
int i = 0;
while (i < 9)
{
Console.WriteLine("How bad thread!");
i++;
}
thread1.Join();
thread2.Join();
Console.ReadLine();
}
}
}