假设我有一个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方法。我认为方法也是多线程的一个问题。