我有以下代码启动一些线程:
List<Stuff> lNewStuff = new List<Stuff>();
// populate lNewStuff
for (int i = 0; i < accounts.Length; i++)
{
Account aTemp = _lAccounts.Find(item => item.ID == accounts[i]);
Thread tTemp = new Thread(() => aTemp.ExecuteMe(lNewStuff));
tTemp.Start();
}
然后在Account类中,您拥有具有锁定的ExecuteMe方法:
public class Account
{
private Object lockThis = new Object();
public void ExecuteMe(List<Stuff> lNewStuff)
{
//Ensure only one thread at a time can run this code
lock (lockThis)
{
//main code processing
}
}
}
现在,有时线程以lNewStuff == null开头,因为它有时找不到任何带有帐户ID的新东西。这个项目是正常的。线程应该总是尝试运行,但是当null时我希望这个线程死掉而不是在遇到锁时等待。
具体而言:
如果lNewStuff为null且存在锁定,则终止该线程。 (怎么做?)
如果lNewStuff为空并且没有锁定则正常运行(已经这样做了)
如果lNewStuff不为null且存在锁定,则等待锁定完成(已经这样做了)
如果lNewStuff不为空并且没有锁则则正常运行(已经这样做了)
答案 0 :(得分:3)
当lNewStuff
为空时,您可以使用Monitor.TryEnter
,只有在授予锁定时才会继续:
public class Account
{
private readonly object lockThis = new object();
public void ExecuteMe(List<Stuff> lNewStuff)
{
bool lockTaken = false;
try
{
if (lNewStuff == null)
{
// non-blocking - only takes the lock if it's available
Monitor.TryEnter(lockThis, ref lockTaken);
}
else
{
// blocking - equivalent to the standard lock statement
Monitor.Enter(lockThis, ref lockTaken);
}
if (lockTaken)
{
// main code processing
}
}
finally
{
if (lockTaken)
{
Monitor.Exit(lockThis);
}
}
}
}
答案 1 :(得分:0)
If lNewStuff is null and there is a lock then terminate the thread. (how to do this?) ,
do you want to still start a thread if lNewStuff is Null if answer is no then solution must be very simple.
List<Stuff> lNewStuff = new List<Stuff>();
// populate lNewStuff
for (int i = 0; i < accounts.Length; i++)
{
Account aTemp = _lAccounts.Find(item => item.ID == accounts[i]);
if(lNewStuff!=null)
{
Thread tTemp = new Thread(() => aTemp.ExecuteMe(lNewStuff));
tTemp.Start();
}
}
also you shd create a single lock object
private Object lockThis = new Object(); // this statement is creating new lock object with every account object, and hence does not ensure critical section protection.
将此更改为
private static Object lockThis = new Object();
答案 2 :(得分:0)
只是为了与众不同:
public class Foo : IDisposable
{
private Semaphore _blocker;
public Foo(int maximumAllowed)
{
_blocker = new Semaphore(1,1);
}
public void Dispose()
{
if(_blocker != null)
{
_blocker.Dispose();
_blocker.Close();
}
}
public void LimitedSpaceAvailableActNow(object id)
{
var gotIn = _blocker.WaitOne(0);
if(!gotIn)
{
Console.WriteLine("ID:{0} - No room!", id);
return;
}
Console.WriteLine("ID:{0} - Got in! Taking a nap...", id);
Thread.Sleep(1000);
_blocker.Release();
}
}
试验台:
void Main()
{
using(var foo = new Foo(1))
{
Enumerable.Range(0, 10)
.Select(t =>
Tuple.Create(t, new Thread(foo.LimitedSpaceAvailableActNow)))
.ToList()
.AsParallel()
.ForAll(t => t.Item2.Start(t.Item1));
Console.ReadLine();
}
}
输出:
ID:4 - Got in! Taking a nap...
ID:8 - No room!
ID:0 - No room!
ID:7 - No room!
ID:2 - No room!
ID:6 - No room!
ID:5 - No room!
ID:9 - No room!
ID:1 - No room!
ID:3 - No room!