1

假设我有两种方法-

getCurrentValue(int valueID)
updateValues(int changedComponentID)

这两个方法由不同的线程在同一个对象上独立调用。

getCurrentValue()只需对当前 valueID 进行数据库查找。

Values” 改变如果他们相应的components改变。该updateValues()方法更新那些依赖于刚刚更改的组件的值,即changedComponentID. 这是一个数据库操作,需要时间。

虽然此更新操作正在进行,但我不想通过从数据库中进行查找来返回过时的值,但我想等到更新方法完成。同时,我不希望两个更新操作同时发生,或者在读取进行时发生更新。

所以,我正在考虑这样做 -

[MethodImpl(MethodImplOptions.Synchronized)]
public int getCurrentValue(int valueID)
     {
        while(updateOperationIsGoingOn)
          {
             // do nothing  
          }
        readOperationIsGoingOn = true;

        value = // read value from DB

        readOperationIsGoingOn = false; 
        return value;
     }

[MethodImpl(MethodImplOptions.Synchronized)]
public void updateValues(int componentID)
     {
         while(readOperationIsGoingOn)
          {
             // do nothing
          }
         updateOperationIsGoingOn = true;

         // update values in DB

         updateOperationIsGoingOn = false;
     }

我不确定这是否是正确的做法。有什么建议么?谢谢。

4

3 回答 3

2

在这两种方法之外创建一个静态对象。然后对该对象使用锁定语句;当一种方法访问受保护的代码时,另一种方法将等待锁释放。

private static object _lockObj = new object();

public int getCurrentValue(int valueID)
     {
        object value;

        lock(_lockObj)
          {
           value = // read value from DB
          }
        return value;
     }

public void updateValues(int componentID)
     {
         lock(_lockObj)
          {
         // update values in DB

          }
     }
于 2012-12-17T18:51:12.370 回答
2

这不是正确的方法。像这样你正在做一个“主动等待”,有效地阻塞你的 CPU。

您应该改用锁:

static object _syncRoot = new object();
public int getCurrentValue(int valueID)
{
    lock(_syncRoot)
    {
        value = // read value from DB
    }
}

public void updateValues(int componentID)
{
    lock(_syncRoot)
    {
        // update values in DB
    }
}
于 2012-12-17T18:51:39.203 回答
0
private static readonly object _lock = new object();

public int getCurrentValue(int valueID)
{
    try
    {
        Monitor.Enter(_lock);
        value = // read value from DB
        return value;
    }
    finally
    {
        Monitor.Exit(_lock);
    }
}

public void updateValues(int componentID)
{
    try
    {
        Monitor.Enter(_lock);
        // update values in DB
    }
    finally
    {
        Monitor.Exit(_lock);
    }
}
于 2012-12-17T18:57:04.660 回答