是否有更好的LinkedList线程安全实现

时间:2019-06-25 13:07:36

标签: c# .net multithreading performance concurrency

我正在使用LinkedList,并在存储要更新的数据,对其执行计算和删除旧更新之间进行切换。 要执行此操作,我必须锁定读取和采样部分,但这会带来性能上的提升。 由于我不断添加和删除节点,因此我认为LinkedList是此任务的最佳数据结构(据我所知,为此使用列表将导致复制列表的多种动作) 据我所知,LinkedList没有线程安全的实现。 我正在大量数据上运行此代码,并且需要几个小时才能完成。 有什么办法可以加快速度吗?

编辑:我将节点添加到列表的末尾,并从列表的开头删除

  private readonly ConcurrentQueue<Update> _UpdatesQueue = new   ConcurrentQueue<Update>();
  private volatile bool _AddingUpdates = false;
  public void InsertUpdate(Update update)
        {
            _UpdatesQueue.Enqueue(update);
            if (_AddingUpdates)
            {
                return;
            }

            lock (_updateQueueLock)
            {
                if (_AddingUpdates)
                {
                    return;
                }
                _AddingUpdates = true;
            }
            Task.Factory.StartNew(() =>
            {
                lock (_updateQueueLock)
                {
                    Update lastupdate = null;
                    while (_UpdatesQueue.TryDequeue(out update))
                    {
                        updateWindow.AddLast(update);
                    }
                }
            }).ContinueWith(x =>
            {
                _AddingUpdates = false;
            });
        }

        private volatile bool _Sampling = false;
        private readonly ConcurrentQueue<Tuple<Timestamp, Action<float>>> _RequestsQueue = new ConcurrentQueue<Tuple<Timestamp, Action<float>>>();

        public void GetFeatureAtTime(Timestamp time, Action<float> valueCallback)
        {
            _RequestsQueue.Enqueue(new Tuple<Timestamp, Action<float>>(time, valueCallback));
            if (_Sampling)
            {
                return;
            }

            lock (_updateQueueLock)
            {
                if (_Sampling)
                {
                    return;
                }
                _Sampling = true;
            }
            Task.Factory.StartNew(() =>
            {
                lock (_updateQueueLock)
                {
                    Timestamp lastTime = null;
                    while (_RequestsQueue.TryPeek(out var request))
                    {
                        GetFeatureAtTimeInternal(request.Item1, request.Item2, out var haveEnoughData);
                        if (haveEnoughData)
                        {
                            _RequestsQueue.TryDequeue(out _);
                        }
                        else
                        {
                            break;
                        }
                    }
                }

            }).ContinueWith(x => _Sampling = false);
        }

根据我在VS中的并发可视化工具中看到的信息,有76%的cpu用于同步化。 而且,与插入相比,采样有时可能是一个笨拙的动作。

0 个答案:

没有答案