对象锁感悟
2012-07-18 14:09 田志良 阅读(2514) 评论(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 }