• 并发问题讨论


    高并发效率极其低下,5分钟客户端全部接受反馈,数据库插入尚未执行完毕。

    for (; i < 10000; i++)
    {
                    Thread thread = new Thread(threadStart);
                    thread.Start();
     }

    系统每6秒执行以下操作,做持久化。

    // 作者:                    不要理我 
    // 邮件:               869722304@qq.com(仅仅支持商业合作洽谈)
    // 创建时间:                2012-08-8
    // 最后修改时间:            2012-08-11
    // 
    // 未经修改的文件版权属于原作者所有,但是你可以阅读,修改,调试。本项目不建议商用,不能确保稳定性。
    // 同时由于项目Bug引起的一切问题,原作者概不负责。
    //
    // 本项目所引用的所有类库,仍然遵循其原本的协议,不得侵害其版权。
    //
    // 您一旦下载就视为您已经阅读此声明。
    //
    // 您不可以移除项目中任何声明。
    using CJCMS.Contracts.DTO.Vote;
    using CJCMS.Domain.Entity;
    using CJCMS.Domain.Service;
    using CJCMS.Framework.Logging;
    using CJCMS.Framework.Task;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace CJCMS.Application
    {
        public class VoteTask : IBackgroundTask
        {
            public bool IsWorking { get; set; }
    
            //缓存投票数组
            static Dictionary<string, VoteValueDTO> voteList = new Dictionary<string,VoteValueDTO>();
    
            public VoteTask(bool workFlg)
            {
                IsWorking = true;
            }
    
            //加入新投票
            public static void Add(string key, VoteValueDTO vote)
            {
                //加互斥锁 高并发效率不佳 此处犯愁
                lock (voteList)
                {
                    //判断是否重复投票
                    if (voteList.ContainsKey(key))
                    {
                        throw new Exception("Do not re-vote.");
                    }
                    voteList.Add(key, vote);
                }
            }
    
            //投票持久化数据库,则内存中删除
            public static void Remove(string key)
            {
                lock (voteList)
                {
                    voteList.Remove(key);
                }
            }
    
            //守护函数 每6秒运行一次
            public void DoWork()
            {
                try
                {
                    VoteService service = new VoteService();
                    foreach (KeyValuePair<string, VoteValueDTO> voteValue in voteList)
                    {
                        try
                        {
                            //插入一张投票到数据库 表一行 无其他操作
                            service.DoVote1(AutoMapper.Mapper.Map<VoteValueDTO, VoteValue>(voteValue.Value));
    
                            //删除内存此投票
                            Remove(voteValue.Value.VoteItemId + voteValue.Value.Ip);
                        }
                        catch (Exception ee)
                        {
                            LogHelper.WriteLog(ee.Message);
                        }
                    }
                }
                catch (Exception ee)
                {
                    LogHelper.WriteLog(ee.Message);
                }
            }
        }
    }

    客户端投票执行的接口如下:

    //vote
            public void DoVote(VoteValueDTO voteValue)
            {
                try
                {
                    VoteService service = new VoteService();
                    //查询数据库此ip是否有过投票
                    if (!service.ExistVoteByIp(voteValue.VoteItemId, voteValue.Ip))
                    {
                        //投票
                        VoteTask.Add(voteValue.VoteItemId + voteValue.Ip, voteValue);
                    }
                    else
                    {
                        throw new Exception("Do not re-vote.");
                    }
                    //service.DoVote(AutoMapper.Mapper.Map<VoteValueDTO, VoteValue>(voteValue));
                }
                catch (Exception ee)
                {
                    LogHelper.WriteLog(ee.Message);
                    //throw new Exception("service bussy");
                }
            }

    目前由于数据库插入操作比较费时,队列入内存,每6秒将内存数据持久化。然并发入队列操作,和6秒的持久化操作会同时使用队列,则队列需互斥锁。效率低下。所以想问问大家策略,望大家赐教。

  • 相关阅读:
    关于工作态度
    ajax请求链接加时间戳
    自动消失的提示效果
    表设计原则
    进度展示图
    freemarker时间格式化
    Java的Thread.currentThread().getName() 和 this.getName() 以及 对象.getName()区别???
    使用Github做服务器展示前端页面
    Spring的生命周期
    输入三个字符,从小到大的顺序输出这三个字符
  • 原文地址:https://www.cnblogs.com/ntcj/p/3321458.html
Copyright © 2020-2023  润新知