• 多线程模型一:只完成最新任务


    这个具体的应用场景就是QQ的历史记录管理器里面。当你点击某个联系人时,有个工作线程会去数据库查询对应的聊天记录,一次点击对应一个查询任务。

        1.当没有点击时,线程处于等待状态,一旦有点击,有查询任务,线程唤醒并执行任务。

        2.在线程执行过程中,如果用户又多次点击,只需要执行最后一个点击产生的查询任务即可。

        对应这个需求,我抽象出了一个多线程模型的实现。

    OnlyRunNewestTask.h---------------------------begin--------------------------------

    #pragma once

    namespace ecs
    {
    namespace threadModal
    {

    class ECSUTIL_DllExport Task
    {
    public:
     virtual ~Task()
     {

     }

     virtual void Run() = 0;
    };

    class ECSUTIL_DllExport OnlyRunNewestTaskThread : public  ctk::SimpleThread
    {
    public:
     OnlyRunNewestTaskThread()
      :ctk::SimpleThread(0, "OnlyRunNewestTaskThread")
      ,m_mtx()
      ,m_pTask(NULL)
      ,m_updated(false)
      ,m_break(false)
     {
      
     };

     virtual ~OnlyRunNewestTaskThread() 
     {
      
     };

     void UpdateTask(Task* _data);
     bool GetTask(Task** task);
     void Break();

    protected:
     virtual void run();

    private:
     typedef ctk::Monitor<ctk::Mutex> _Mutex;

     _Mutex m_mtx; 
     Task* m_pTask; 
     bool m_updated;
     volatile bool m_break;
    };

    }
    }

    OnlyRunNewestTask.h---------------------------end--------------------------------

     

    OnlyRunNewestTask.cpp---------------------------begin--------------------------------

    #include "ecsutil_prec.h"
    #include "ecsutil/threadModal/OnlyRunNewestTask.h"

    using namespace ecs::threadModal;

    void OnlyRunNewestTaskThread::UpdateTask(Task* _data)

     _Mutex::Lock lck(m_mtx);
     delete m_pTask;
     m_pTask = _data;
     m_updated = true;
     m_mtx.notify();
    }

    bool OnlyRunNewestTaskThread::GetTask(Task** task)
    {
     _Mutex::Lock lck(m_mtx);
     if (!m_updated)
     {
      m_mtx.wait();
     }
     if (m_updated) 
     {
      *task = m_pTask;
      m_pTask = NULL;
      m_updated = false;
      return true;
     }
     return false;
    }

    void OnlyRunNewestTaskThread::Break()
    {
     m_break = true;
     UpdateTask(NULL);
    }

    void OnlyRunNewestTaskThread::run()
    {
     Task* taskData = NULL;
     while(GetTask(&taskData) && !m_break)
     {
      taskData->Run();
      delete taskData;
     }
    }

    OnlyRunNewestTask.cpp---------------------------end--------------------------------

     

        这种场景用这种解决方案是合适的。这个实现还有个缺点,在新任务来的时候,没有考虑中止执行旧任务。

        Task在这里就是个空壳,作用是为了抽离出独立的多线程模型代码。外界要使用这个实现代码,只需要写个具体的任务类,然后继承Task即可。要达到一样的效果,有没有更好的实现,求高手指教。

     

  • 相关阅读:
    Apache Poi 操作word,替换字符保留样式问题,runs段落混乱问题。
    C# 文件打包下载
    git eclipse 切换分支,出现很多的历史分支 清理操作
    Centos7添加ip白名单
    技术随笔3
    技术随笔2
    6 Python编程:从入门到实践用户输入和while循环 摩天居士
    7 Python编程:从入门到实践函数 摩天居士
    8 Python编程:从入门到实践类 摩天居士
    学习Python必刷的100道经典练习题,没练等于白学 摩天居士
  • 原文地址:https://www.cnblogs.com/towik/p/3199691.html
Copyright © 2020-2023  润新知