如何使静态变量线程安全 [英] How to make a static variable thread-safe
问题描述
我有一个包含静态变量(一个简单的int)的静态类.我已经在线程的Run()
方法中实现了lock()
,因此没有其他线程可以同时访问该类,但是该变量仍然发疯,显示重复项,疯狂的高值等.
I have this static class which contains a static variable (a simple int). I've implemented a lock()
in the Run()
method of the threads, so no other threads can access to this class concurrently, but the variable still goes crazy, displaying duplicates, insanely high values, etc.
这是课程:
public static class ExplorationManager
{
public static int Counter = 0;
public static void ExplorerMaker(List<int[]> validPaths, List<string> myParents, string[,] myExplorationMap, List<int[]> myPositions)
{
foreach (var thread in validPaths.Select
(path => new Explorer(myParents, path, myExplorationMap, myPositions)).
Select(explorer => new Thread(explorer.Explore)))
{
thread.Name = "Thread of " + Counter + " generation";
Counter++;
thread.Start();
}
}
}
有没有办法使此变量更多"具有线程安全性?
Is there a way to make this variable "more" thread-safe?
推荐答案
您至少需要解决两个问题,以提高这种类型的安全性.
There are at least 2 problems that you need to address in order to increase the safety of this type.
第一个是制作Counter
private
.按照目前的形式,该变量是100%公开的,并且可以由应用程序中的任何代码段进行更改.今天它可能很安全,但是没有任何东西可以保护您明天不会犯错误.如果您仍然希望其他代码段能够读取该属性,请使用访问器
The first one is to make Counter
private
. In it's current form the variable is 100% public and it can be mutated by any piece of code in the application. Today it may be safe but there's nothing protecting you from making a mistake tomorrow. If you still want other pieces of code to be able to read the property then use an accessor
private static int m_counter;
public static int Counter {
get { return m_counter; }
}
第二个问题是++
在线程之间共享的位置上不是安全的操作.它扩展为以下代码
The second problem is that ++
isn't a safe operation on a location that is shared amongst threads. It expands out to the following code
Counter = Counter + 1;
实际上在做什么
- 负载计数器
- 加载1
- 添加
- 商店柜台
线程几乎可以在任何时间中断.如果一个线程在第1、2或3步被中断,而另一个线程完全执行了该序列,那么您最终将添加/存储陈旧的值.这就是++
不安全的原因.在线程之间增加共享值的安全方法是使用Interlocked.Increment
.正是为此目的而设计的
A thread can be interrupted an virtually any time. If one thread is interrupted at step 1, 2 or 3 and another thread fully executes the sequence then you will end up adding / storing stale values. This is why ++
is unsafe. The safe way to increment a shared value amongst threads is to use Interlocked.Increment
. It's designed exactly for this purpose
Interlocked.Increment(ref m_counter);
这篇关于如何使静态变量线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!