如何使静态变量线程安全 [英] How to make a static variable thread-safe

查看:371
本文介绍了如何使静态变量线程安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含静态变量(一个简单的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. 负载计数器
  2. 加载1
  3. 添加
  4. 商店柜台

线程几乎可以在任何时间中断.如果一个线程在第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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆