代码改变世界

对象锁感悟

2012-07-18 14:09  田志良  阅读(...)  评论(... 编辑 收藏

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

    }