当多线程我知道我需要锁定变量,如果做一些事情,如添加和项目到列表等,或者我会得到一个跨线程异常。但是在分配变量时我是否需要锁定它们?我不介意线程是否获得变量的旧实例 - 我只是不希望它出错。这是我的意思的一个例子:
public void Run()
{
var thread1 = new Thread(new ThreadStart(Test));
var thread2 = new Thread(new ThreadStart(Test));
thread1.Start();
thread2.Start();
}
private static int _test;
private void Test()
{
while (true)
{
_test += 1;
}
}
答案 0 :(得分:5)
如果你只是分配一个int
,那么没有。但在这里,你不只是分配。你正在递增。所以你需要某种同步。
如果您想要增加,请使用Interlocked.Increment:
Interlocked.Increment(ref _test);
答案 1 :(得分:0)
你必须记住线程也可能正在查看陈旧的副本,通过锁定你确保正在刷新的变量版本正在刷新
当我第一次开始编码并认为可能我不需要变量的最新副本时,我会陷入无限循环,因为我假设变量最终会更新,但如果变量被缓存则会永远不会更新
我包含了简短描述的示例,不用担心线程的启动方式,这是不相关的
private static bool _continueLoop = true;
private static readonly object _continueLoopLock = new object();
private static void StopLoop()
{
lock(_continueLoopLock)
_continueLoop = false;
}
private static void ThreadALoopWillGetStales()
{
while(_continueLoop)
{
//do stuff
//this is not guaranteed to end
}
}
private static void ThreadALoopEventuallyCorrect()
{
while(true)
{
bool doContinue;
lock(_continueLoopLock)
doContinue = _continueLoop;
if(!doContinue)
break;
//do stuff
//this will sometimes result in a stale value
//but will eventually be correct
}
}
private static void ThreadALoopAlwaysCorrect()
{
while(true)
{
bool doContinue;
lock(_continueLoopLock)
if(!_continueLoop)
break;
//do stuff
//this will always be correct
}
}
private static void ThreadALoopPossibleDeadlocked()
{
lock(_continueLoopLock)
while(_continueLoop)
{
//if you only modify "_continueLoop"
//after Acquiring "_continueLoopLock"
//this will cause a deadlock
}
}
private static void StartThreadALoop()
{
ThreadPool.QueueUserWorkItem ((o)=>{ThreadALoopWillGetStales();});
}
private static void StartEndTheLoop()
{
ThreadPool.QueueUserWorkItem((o)=>
{
//do stuff
StopLoop();
});
}
public static void Main(string[] args)
{
StartThreadALoop();
StartEndTheLoop();
}
当你开始循环时,你有可能继续获得变量的陈旧副本,这就是为什么你做在访问多个线程时需要某种同步
答案 2 :(得分:0)
运行代码应该给你答案......而不是while(true)
写for(i=1;1<1e6;i++)
,将结果写入屏幕并运行它。
你会发现它并不是2e6,而是1.2e6左右。所以,是的,如果你想离开2e6,你需要锁定。
不要只是假设,之后总是测试和断言。