我有成千上万的整数的查找表(LUT),我就请求基于什么是从数据库中提取计算的东西相当数量的使用。

如果我简单地创建一个标准单保持LUT,是它自动请求之间持续或我特别需要将其推到应用程序状态?

如果它们被自动持续存在,则差值存储它们与应用程序的状态是什么?

如何将一个正确的单身实现是什么样子?它并不需要被延迟初始化,但它需要是线程安全的(千每个服务器实例理论的用户),并有不错的表现。

编辑:乔恩斯基特的第四版本看起来很有希望 http://csharpindepth.com/Articles/General /Singleton.aspx

public sealed class Singleton
{
    static readonly Singleton instance=new Singleton();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }

    // randomguy's specific stuff. Does this look good to you?
    private int[] lut = new int[5000];

    public int Compute(Product p) {
        return lut[p.Goo];
    }
}
有帮助吗?

解决方案

是,静态成员仍然存在(如不坚持同样的事情 - 这不是“救”,它永远不会消失),其中将包括一个单独的实现。你得到一定程度的暂缓初始化的自由,好像是在一个静态分配或静态构造函数创建的,它不会被调用,直到第一次使用的相关类。默认情况下,这个创作锁,但所有其他用途必须是线程安全的,你说的。由于并发的参与程度,则除非单将是不可变的(你的查表不应用生命周期变化),你必须要非常小心,因为你如何更新(单程是假单 - 在更新您创建一个新的对象,然后锁定起来分配给它来取代当前值,不是严格意义上的单身,虽然它看起来像一个“从外面”)

在大的危险是无状态协议,如网络打交道时任何事情引入全局状态是犯罪嫌疑人,特别是。它可以用来很好虽然,特别是作为永久或接近永久数据的内存中缓存,尤其是当它涉及不容易快速地从数据库中获得一个对象图。

在缺陷是相当大的,虽然,所以要小心。特别是,锁定问题的风险不能被低估。

编辑,到编辑匹配的问题是:

我的大问题将是数组被初始化如何。显然,这个例子是不完整的,因为它只会曾经有0每个项目。如果它获得一套在初始化,并且是只读的,然后罚款。如果它是可变的,则是非常,非常小心你的线程。

另外要注意的上缩放太多这样的查找窗口的负面影响。当你在有预先计算的mosts请求保存,效果是有一段非常繁重的工作时,单被更新。长十岁上下的启动很可能会容忍(因为它不会很频繁),但任意缓慢起伏之后发生的事情可能会非常棘手追查其来源。

其他提示

我不会依赖一个静态的存在坚持请求之间。 [总是有,虽然不太可能,机会,过程将请求之间进行复位。]我推荐的HttpContext对请求之间持续共享资源的Cache对象。

编辑:见乔恩的有关只读锁定

评论

这已经有一段时间,因为我已经经历了单身的(我宁愿让我的IOC容器处理寿命),但在这里,你可以如何处理线程安全问题。你需要锁定围绕任何变异单身的状态。只读操作,如您Compute(int)将不再需要锁定。

// I typically create one lock per collection, but you really need one per set of atomic operations; if you ever modify two collections together, use one lock.
private object lutLock = new object();
private int[] lut = new int[5000];

public int Compute(Product p) {
    return lut[p.Goo];
}

public void SetValue(int index, int value)
{
    //lock as little code as possible. since this step is read only we don't lock it.
    if(index < 0 || index > lut.Length)
    {
        throw new ArgumentException("Index not in range", "index");
    }
    // going to mutate state so we need a lock now
    lock(lutLock)
    {
        lut[index] = value;
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top