如何在一个类不再被任何线程

时间:2016-07-04 22:43:42

标签: c# multithreading locking

假设我有一个Map类,其中有一些数据只用于就绪,并且有多个工作者(线程)同时使用此类。

如果我想在任何工作人员不再使用该地图实例时清除该地图实例(擦除它的数据),我将如何以线程安全的方式有效地执行此操作?

这样的事情:

public class Map
{
    public static Map activeMap;
    public int used;

    public void BeginWork()
    {
        System.Threading.Interlocked.Increment(ref used);
    }

    public void EndWork()
    {
        System.Threading.Interlocked.Decrement(ref used);

        if(this != activeMap && used == 0)
        {
            Erase();
        }
    }

    // This method is only called on the main thread.
    public static void ChangeActiveMap(Map newActiveMap)
    {
        Map previousMap = activeMap;
        activeMap = newActiveMap;
        if (previousMap.used == 0) 
        {
            previousMap.Erase();
        }
    }

    private void Erase()
    {
        // Erase Map data here.
        // Put Map into a pool for later use and prevent it from going to GC.
    }
}

public class Worker
{
    private Map map;

    public void BeginWork()
    {
        Map.activeMap.BeginWork();
        map = Map.activeMap;

        //  Do work here with map data.

        map.EndWork();
        map = null;
    }
}

如果地图在工作人员仍在使用时被删除,则工作人员将处理空白地图数据,这将导致错误。我觉得上面的代码不能正常工作。如果不使用锁,这真的是一个加分。

编辑:地图数据太昂贵了,无法进入GC,使用Clear方法的想法是回收它并将其放入池中供以后使用而无需进入GC。

也许代码可以正常运行,假设只有在不再是activeMap的情况下它才会被清除,因为新工作者只会用activeMap开始新的工作?

编辑:在代码中添加了ChangeActiveMap方法。我认为方法也是多线程的一个问题。

0 个答案:

没有答案