对象锁感悟
2012-07-18 14:09 田志良 阅读(2528) 评论(1) 收藏 举报1、对于一个对象,读取对象元素无须加锁,增加、修改、删除、遍历须加锁。
2、如果对象a包含另外一个对象b,针对对象a的操作只要锁住对象a,针对对象b的操作只要锁住对象b。
3、如果对象a包含对象b,对象b包含对象c,对c的操作可以锁住c,可以锁住b,也可以锁住a,至于锁哪个,据具体的业务逻辑性能要求来定。
4、有时为了防止并发覆盖,可扩大锁范围。
注意,锁住的对象不能为null。
用户缓存对象锁示例:
internal class InternalUserCache : IUserCache
{
/// <summary>
/// 添加用户
/// </summary>
/// <param name="userId"></param>
/// <param name="groupList"></param>
/// <param name="friendList"></param>
public void AddUser(string userId, List<string> groupList, List<string> friendList)
{
try
{
UserToken userToken = new UserToken();
userToken.GroupList = groupList;
userToken.FriendsList = friendList;
lock (BusinessCacheParameter.UserHash.SyncRoot)
{
BusinessCacheParameter.UserHash[userId] = userToken;
}
}
catch (Exception ex)
{
throw new Exception("InternalUserCache AddUser出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 添加用户好友
/// </summary>
/// <param name="userId"></param>
/// <param name="friendId"></param>
public void AddUserFriend(string userId, string friendId)
{
try
{
UserToken userToken = (UserToken)BusinessCacheParameter.UserHash[userId];
if (userToken != null)
{
lock (userToken)
{
List<string> friendsList = userToken.FriendsList;
if (friendsList != null && !friendsList.Contains(friendId))
{
friendsList.Add(friendId);
}
}
}
}
catch (Exception ex)
{
throw new Exception("InternalUserCache AddUserFriend出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 添加用户群组
/// </summary>
/// <param name="userId"></param>
/// <param name="groupId"></param>
public void AddUserGroup(string userId, string groupId)
{
try
{
UserToken userToken = (UserToken)BusinessCacheParameter.UserHash[userId];
if (userToken != null)
{
lock (userToken)
{
List<string> groupList = userToken.GroupList;
if (groupList != null && !groupList.Contains(groupId))
{
groupList.Add(groupId);
}
}
}
}
catch (Exception ex)
{
throw new Exception("InternalUserCache AddUserGroup出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 判断当前用户是否在线
/// true : 在线
/// false : 不在线
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public bool CheckOnLine(string userId)
{
try
{
if (BusinessCacheParameter.UserHash.Contains(userId))
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
throw new Exception("InternalUserCache CheckOnLine出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 删除用户
/// </summary>
/// <param name="userId"></param>
public void DelUser(string userId)
{
try
{
lock (BusinessCacheParameter.UserHash.SyncRoot)
{
BusinessCacheParameter.UserHash.Remove(userId);
}
}
catch (Exception ex)
{
throw new Exception("InternalUserCache DelUser出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 删除用户好友
/// </summary>
/// <param name="userId"></param>
/// <param name="friendId"></param>
public void DelUserFriend(string userId, string friendId)
{
try
{
UserToken userToken = (UserToken)BusinessCacheParameter.UserHash[userId];
if (userToken != null)
{
lock (userToken)
{
List<string> friendsList = userToken.FriendsList;
if (friendsList != null)
{
friendsList.Remove(friendId);
}
}
}
}
catch (Exception ex)
{
throw new Exception("InternalUserCache DelUserFriend出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 删除用户群组
/// </summary>
/// <param name="userId"></param>
/// <param name="groupId"></param>
public void DelUserGroup(string userId, string groupId)
{
try
{
UserToken userToken = (UserToken)BusinessCacheParameter.UserHash[userId];
if (userToken != null)
{
lock (userToken)
{
List<string> groupList = userToken.GroupList;
if (groupList != null)
{
groupList.Remove(groupId);
}
}
}
}
catch (Exception ex)
{
throw new Exception("InternalUserCache DelUserGroup出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 获取所有在线人员
/// </summary>
/// <returns></returns>
public string[] GetOnlineUsers()
{
try
{
string[] userArray;
lock (BusinessCacheParameter.UserHash.SyncRoot)
{
userArray = new string[BusinessCacheParameter.UserHash.Count];
BusinessCacheParameter.UserHash.Keys.CopyTo(userArray, 0);
}
return userArray;
}
catch (Exception ex)
{
throw new Exception("InternalUserCache GetOnlineUsers出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 获取所有在线人数
/// </summary>
/// <returns></returns>
public int GetCountOfOnlineUsers()
{
try
{
return BusinessCacheParameter.UserHash.Count;
}
catch (Exception ex)
{
throw new Exception("InternalUserCache GetCountOfOnlineUsers出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 获取用户所有好友
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public List<string> GetUserFriends(string userId)
{
try
{
List<string> returnResult = new List<string>();
UserToken userToken = (UserToken)BusinessCacheParameter.UserHash[userId];
if (userToken != null)
{
lock (userToken)
{
if (userToken.FriendsList != null)
{
foreach (string str in userToken.FriendsList)
{
returnResult.Add(str);
}
}
}
}
return returnResult;
}
catch (Exception ex)
{
throw new Exception("InternalUserCache GetUserFriends出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 获取用户所有群组
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public List<string> GetUserGroups(string userId)
{
try
{
List<string> returnResult = new List<string>();
UserToken userToken = (UserToken)BusinessCacheParameter.UserHash[userId];
if (userToken != null)
{
lock (userToken)
{
if (userToken.GroupList != null)
{
foreach (string str in userToken.GroupList)
{
returnResult.Add(str);
}
}
}
}
return returnResult;
}
catch (Exception ex)
{
throw new Exception("InternalUserCache GetUserGroups出错,错误描述为:" + ex.Message.ToString());
}
}
}
[Serializable]
internal class UserToken
{
#region 字段
private List<string> m_GroupList; //群组列表
private List<string> m_FriendList; //好友列表
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
public UserToken()
{ }
#endregion
#region 属性
/// <summary>
/// 群组列表
/// </summary>
internal List<string> GroupList
{
get
{
return this.m_GroupList;
}
set
{
this.m_GroupList = value;
}
}
/// <summary>
/// 好友列表
/// </summary>
internal List<string> FriendsList
{
get
{
return this.m_FriendList;
}
set
{
this.m_FriendList = value;
}
}
#endregion
}
群组缓存对象锁示例:
internal class InternalGroupCache : IGroupCache
{
/// <summary>
/// 获取群组所有成员
/// </summary>
/// <param name="groupId"></param>
/// <returns></returns>
public List<string> GetGroupMembers(string groupId)
{
try
{
List<string> returnResult = new List<string>();
GroupToken groupToken = (GroupToken)BusinessCacheParameter.GroupHash[groupId];
if (groupToken != null)
{
lock (groupToken)
{
if (groupToken.UserList != null)
{
foreach (string str in groupToken.UserList)
{
returnResult.Add(str);
}
}
}
}
return returnResult;
}
catch (Exception ex)
{
throw new Exception("InternalGroupCache GetGroupMembers出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 获取群组成员人数
/// </summary>
/// <param name="groupId"></param>
/// <returns></returns>
public int GetCountOfGroupUsers(string groupId)
{
try
{
int returnResult = 0;
GroupToken groupToken = (GroupToken)BusinessCacheParameter.GroupHash[groupId];
if (groupToken != null && groupToken.UserList != null)
{
returnResult = groupToken.UserList.Count;
}
return returnResult;
}
catch (Exception ex)
{
throw new Exception("InternalGroupCache GetCountOfGroupUsers出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 删除群组成员
/// </summary>
/// <param name="groupId"></param>
/// <param name="userId"></param>
public void DelGroupMember(string groupId, string userId)
{
try
{
GroupToken groupToken = (GroupToken)BusinessCacheParameter.GroupHash[groupId];
if (groupToken != null)
{
lock (groupToken)
{
List<string> userList = groupToken.UserList;
if (userList != null)
{
userList.Remove(userId);
}
}
}
}
catch (Exception ex)
{
throw new Exception("InternalGroupCache DelGroupMember出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 删除群组
/// </summary>
/// <param name="groupId"></param>
public void DelGroup(string groupId)
{
try
{
lock (BusinessCacheParameter.GroupHash.SyncRoot)
{
BusinessCacheParameter.GroupHash.Remove(groupId);
}
}
catch (Exception ex)
{
throw new Exception("InternalGroupCache DelGroup出错,错误描述为:" + ex.Message.ToString());
}
}
/// <summary>
/// 添加群组成员
/// </summary>
/// <param name="groupId"></param>
/// <param name="userId"></param>
public void AddGroupMember(string groupId, string userId)
{
try
{
// 此处扩大锁范围,防止相同群组下的不同用户出现并发覆盖
lock (BusinessCacheParameter.GroupHash.SyncRoot)
{
GroupToken groupToken = (GroupToken)BusinessCacheParameter.GroupHash[groupId];
if (groupToken != null)
{
List<string> userList = groupToken.UserList;
if (userList == null)
{
userList = new List<string>();
userList.Add(userId);
groupToken.UserList = userList;
}
else
{
if (!userList.Contains(userId))
{
userList.Add(userId);
}
}
}
else
{
groupToken = new GroupToken();
List<string> userList = new List<string>();
userList.Add(userId);
groupToken.UserList = userList;
BusinessCacheParameter.GroupHash[groupId] = groupToken;
}
}
}
catch (Exception ex)
{
throw new Exception("InternalGroupCache AddGroupMember出错,错误描述为:" + ex.Message.ToString());
}
}
}
[Serializable]
internal class GroupToken
{
#region 字段
private List<string> m_UserList; //用户列表
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
public GroupToken()
{ }
#endregion
#region 属性
/// <summary>
/// 用户列表
/// </summary>
internal List<string> UserList
{
get
{
return this.m_UserList;
}
set
{
this.m_UserList = value;
}
}
#endregion
}
浙公网安备 33010602011771号