大神帮忙看看下面多线程中关于锁的使用存在的问题

 #include <stdio.h>
#include <process.h>
#include <windows.h>
#include <string>

class IAnimalActionObserver
{
public:
    IAnimalActionObserver(){}
    virtual ~IAnimalActionObserver(){}
    virtual void OnAnimalEat() = 0;
};

class Animal
{
public:
    Animal()
        : observer_(NULL)
    {
        _beginthreadex(NULL, 0, ThreadFun, this, 0, NULL);
    }
    virtual ~Animal(){}

    virtual void RegsiterActionObserver(IAnimalActionObserver* observer)
    {
        observer_ = observer;
    }
    virtual void DeregsiterActionObserver()
    {
        observer_ = NULL;
    }

private:
    static unsigned int _stdcall ThreadFun(void* args)
    {
        (static_cast<Animal*>(args))->ThreadLoop();
        return 0;
    }
    void ThreadLoop()
    {
        while (true)
        {
            if (observer_)
            {
                observer_->OnAnimalEat();
            }
            Sleep(2 * 1000);
        }
    }

private:
    IAnimalActionObserver* observer_;
};

class Cat
    : public IAnimalActionObserver
{
    struct CatInfo
    {
        CatInfo():eat_count_(0){}
        int eat_count_;
        std::string str_msg_;
    };
public:
    Cat()
    {
        InitializeCriticalSection(&cs_);
        _beginthreadex(NULL, 0, ThreadFun1, this, 0, NULL);
        _beginthreadex(NULL, 0, ThreadFun2, this, 0, NULL);
    }
    virtual ~Cat()
    {

    }

    virtual void OnAnimalEat()
    {
        printf("cat eat a fish.\n");
        EatFinish();
    }

private:
    static unsigned int _stdcall ThreadFun1(void* args)
    {
        (static_cast<Cat*>(args))->ThreadLoop1();
        return 0;
    }
    void ThreadLoop1()
    {
        while (true)
        {
            animal_.RegsiterActionObserver(this);
            Sleep(2 * 1000);
            animal_.DeregsiterActionObserver();
            msg_.str_msg_ = "cat eating fish\n";
            msg_.eat_count_++;
            if (msg_.eat_count_ >= 5)
            {
                break;
            }
        }
    }
    static unsigned int _stdcall ThreadFun2(void* args)
    {
        (static_cast<Cat*>(args))->ThreadLoop2();
        return 0;
    }
    void ThreadLoop2()
    {
        while (true)
        {
            EnterCriticalSection(&cs_);
            if (msg_.eat_count_ >= 5)
            {
                msg_.str_msg_ = "cat eat finish\n";
                EatFinish();
                break;
            }
            LeaveCriticalSection(&cs_);
        }
    }
    void EatFinish()
    {
        EnterCriticalSection(&cs_);
        if (msg_.eat_count_ >= 5)
        {
            printf(msg_.str_msg_.c_str());
            msg_.eat_count_ = 0;
            msg_.str_msg_.empty();
            animal_.DeregsiterActionObserver();
        }
        LeaveCriticalSection(&cs_);
    }

private:
    Animal animal_;
    CRITICAL_SECTION cs_;
    CatInfo msg_;
};

int main()
{
    Cat cat_;
    while (1)
    {
        Sleep(1000);
    }
    return 0;
}