zoukankan      html  css  js  c++  java
  • 多线程模型一:只完成最新任务

    这个具体的应用场景就是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即可。要达到一样的效果,有没有更好的实现,求高手指教。

     

  • 相关阅读:
    CachedRowSet使用
    mybatis There is no getter for property named 'xx' in 'class java.lang.String
    基于tcpdump的Android智能移动终端数据包捕获完整解决方案
    analytics详解
    android开发图片分辨率
    缩放图片,解决bitmap 内存溢出out of memory的问题
    使用windowAnimations定义Activity及Dialog的进入退出效果
    读取本地已有的.db数据库
    MyBatis 问题列表
    cxf 相关问题
  • 原文地址:https://www.cnblogs.com/towik/p/3199691.html
Copyright © 2011-2022 走看看