我需要锁定一个对象(集合),执行一些操作并调用一个使用ThreadPool打开线程的函数(在同一个锁定块中)。
我的问题是,新线程内部执行的操作仍然被视为线程安全吗?
答案 0 :(得分:3)
没有。新线程的代码在其自己的上下文中运行,lock
语句(实际上只是一种调用Monitor.Enter
的便捷方式)在每个线程的基础上运行。
答案 1 :(得分:2)
您可能会在线程完成其作业之前释放锁定,除非您等待它退出。
lock(collection){
DoSomeWork();
LaunchNewThread(); => newThread starts
} => the lock will likely be released BEFORE newThread ends
所以你必须等待newThread完成才能释放锁。理想的解决方案是在newThread中执行所有操作(锁定和DoSomeWork)。如果那不可能,你可以创建另一个锁定的线程,并等待newThread结束:
anotherThread{
lock(collection){
DoSomeWork();
LaunchNewThread();
newThread.JOIN(); => execution will stop until newThread finishes
} => the lock will be released AFTER newThread returns
}
答案 2 :(得分:1)
在这里看一下我的帖子: http://pilpag.blogspot.dk/2016/04/advanced-programming-easy-way-to-manage.html
简而言之,请使用以下代码: 公共类LockContainer { private BlockingCollection lockItems {get;组; }
private object LocalLockItem { get; set; }
public LockContainer()
{
lockItems = new BlockingCollection<object>();
LocalLockItem = new object();
}
public object GetLockItem(string str)
{
lock (LocalLockItem)
{
if (!lockItems.Any(li => (string)li == str))
{
lockItems.Add(str);
}
return lockItems.First(li => (string)li == str);
}
}
}