cocos2dx多线程以及线程同步 与 cocos2dx内存管理与多线程问题
cocos2d-x引擎在内部实现了一个庞大的主循环,每帧之间更新界面,如果耗时的操作放到了主线程中,游戏的界面就会卡,这是不能容忍的,游戏最基本的条件就是流畅性,这就是为什么游戏开发选择C++的原因。另外现在双核手机和四核手机越来越普遍了,是时候使用多线程来挖掘硬件的潜力了。
1.环境搭建
接着添加附加包含目录,右击项目,属性----->C/C++---->常规----->附加包含目录加入pthread头文件所在的目录
2.多线程的使用
- PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,//线程的标示
- const pthread_attr_t * attr, //创建线程的参数
- void *(*start) (void *), //入口函数的指针
- void *arg); //传递给线程的数据
- PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,//线程的标示
- const pthread_attr_t * attr, //创建线程的参数
- void *(*start) (void *), //入口函数的指针
- void *arg); //传递给线程的数据
在HelloWorldScene.h文件中
- pthread_t pidrun,pidgo;
- static void* th_run(void *r);
- static void* th_go(void *r);
- pthread_t pidrun,pidgo;
- static void* th_run(void *r);
- static void* th_go(void *r);
定义了两个函数和两个线程的标识。
然后自定义了一个类,用于给线程传递数据。Student类如下:
- #pragma once
- #include <string>
- class Student
- {
- public:
- Student(void);
- Student(std::string name,int age,std::string sex);
- ~Student(void);
- std::string name;
- int age;
- std::string sex;
- };
- #pragma once
- #include <string>
- class Student
- {
- public:
- Student(void);
- Student(std::string name,int age,std::string sex);
- ~Student(void);
- std::string name;
- int age;
- std::string sex;
- };
源文件如下
- #include "Student.h"
- #include "cocos2d.h"
- Student::Student(void)
- {
- }
- Student::~Student(void)
- {
- cocos2d::CCLog("delete data");
- }
- Student::Student(std::string name,int age,std::string sex)
- {
- this->name=name;
- this->age=age;
- this->sex=sex;
- }
- #include "Student.h"
- #include "cocos2d.h"
- Student::Student(void)
- {
- }
- Student::~Student(void)
- {
- cocos2d::CCLog("delete data");
- }
- Student::Student(std::string name,int age,std::string sex)
- {
- this->name=name;
- this->age=age;
- this->sex=sex;
- }
在退出菜单的回调函数中启动两个线程:
- void HelloWorld::menuCloseCallback(CCObject* pSender)
- {
- Student *temp=new Student(std::string("zhycheng"),23,std::string("male"));
- pthread_mutex_init(&mutex,NULL);
- pthread_create(&pidrun,NULL,th_run,temp);//启动线程
- pthread_create(&pidgo,NULL,th_go,0);
- }
- void HelloWorld::menuCloseCallback(CCObject* pSender)
- {
- Student *temp=new Student(std::string("zhycheng"),23,std::string("male"));
- pthread_mutex_init(&mutex,NULL);
- pthread_create(&pidrun,NULL,th_run,temp);//启动线程
- pthread_create(&pidgo,NULL,th_go,0);
- }
可以看到,将Student的指针传递给了pidrun线程,那么在pidrun线程中获得Student信息如下:
- Student *s=(Student*)(r);
- CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());
- delete s;
- Student *s=(Student*)(r);
- CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());
- delete s;
3.线程同步
使用了线程,必然就要考虑到线程同步,不同的线程同时访问资源的话,访问的顺序是不可预知的,会造成不可预知的结果。
这里使用pthread_mutex_t来实现同步,下面我来演示一下使用多线程实现卖票系统。卖票的时候,是由多个窗口同时卖票,这里要做到一张票不要卖出去两次,不要出现有票却无法卖的结果。
在线程函数th_run和th_go中来卖票,票的数量是一个全局变量,每卖出去一张票,就将票的数量减一。其中同步的pthread_mutex_t也是一个全局变量,就用它来实现线程同步。
- void* HelloWorld::th_run(void *r)
- {
- Student *s=(Student*)(r);
- CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());
- delete s;
- while(true)
- {
- pthread_mutex_lock(&mutex);
- if(ticket>0)
- {
- CCLog("thread run sell %d",ticket);
- ticket--;
- pthread_mutex_unlock(&mutex);
- }
- else
- {
- pthread_mutex_unlock(&mutex);
- break;
- }
- Sleep(1);
- //Usleep(10);
- }
- return NULL;
- }
- void* HelloWorld::th_run(void *r)
- {
- Student *s=(Student*)(r);
- CCLog("name is %s,and age is %d,sex is %s",s->name.c_str(),s->age,s->sex.c_str());
- delete s;
- while(true)
- {
- pthread_mutex_lock(&mutex);
- if(ticket>0)
- {
- CCLog("thread run sell %d",ticket);
- ticket--;
- pthread_mutex_unlock(&mutex);
- }
- else
- {
- pthread_mutex_unlock(&mutex);
- break;
- }
- Sleep(1);
- //Usleep(10);
- }
- return NULL;
- }
- void* HelloWorld::th_go(void *r)
- {
- while(true)
- {
- pthread_mutex_lock(&mutex);
- if(ticket>0)
- {
- CCLog("thread go sell %d",ticket);
- ticket--;
- pthread_mutex_unlock(&mutex);
- }
- else
- {
- pthread_mutex_unlock(&mutex);
- break;
- }
- Sleep(1);
- }
- return NULL;
- }
- void* HelloWorld::th_go(void *r)
- {
- while(true)
- {
- pthread_mutex_lock(&mutex);
- if(ticket>0)
- {
- CCLog("thread go sell %d",ticket);
- ticket--;
- pthread_mutex_unlock(&mutex);
- }
- else
- {
- pthread_mutex_unlock(&mutex);
- break;
- }
- Sleep(1);
- }
- return NULL;
- }
mutex被锁定后,其他线程若再想锁定mutex的话,必须等待,当该线程释放了mutex之后,其他线程才能锁定mutex。Sleep()函数可以使得该线程休眠,单位是毫秒。下面是卖票的结果:
- name is zhycheng,and age is 23,sex is male
- delete data
- thread run sell 100
- thread run sell 99
- thread go sell 98
- thread go sell 97
- thread run sell 96
- thread go sell 95
- thread go sell 94
- thread run sell 93
- thread go sell 92
- thread run sell 91
- thread go sell 90
- thread go sell 89
- thread run sell 88
- thread go sell 87
- thread run sell 86
- thread go sell 85
- thread run sell 84
- thread go sell 83
- thread run sell 82
- thread go sell 81
- thread run sell 80
- thread go sell 79
- thread run sell 78
- thread go sell 77
- thread run sell 76
- thread go sell 75
- thread run sell 74
- thread go sell 73
- thread run sell 72
- thread go sell 71
- thread run sell 70
- thread go sell 69
- thread go sell 68
- thread run sell 67
- thread go sell 66
- thread run sell 65
- thread go sell 64
- thread run sell 63
- thread go sell 62
- thread run sell 61
- thread go sell 60
- thread run sell 59
- thread go sell 58
- thread run sell 57
- thread go sell 56
- thread run sell 55
- thread go sell 54
- thread run sell 53
- thread run sell 52
- thread go sell 51
- thread run sell 50
- thread go sell 49
- thread run sell 48
- thread go sell 47
- thread run sell 46
- thread go sell 45
- thread run sell 44
- thread run sell 43
- thread go sell 42
- thread run sell 41
- thread run sell 40
- thread go sell 39
- thread run sell 38
- thread run sell 37
- thread run sell 36
- thread run sell 35
- thread go sell 34
- thread run sell 33
- thread run sell 32
- thread go sell 31
- thread run sell 30
- thread run sell 29
- thread run sell 28
- thread run sell 27
- thread run sell 26
- thread run sell 25
- thread go sell 24
- thread run sell 23
- thread go sell 22
- thread go sell 21
- thread run sell 20
- thread go sell 19
- thread run sell 18
- thread run sell 17
- thread go sell 16
- thread run sell 15
- thread go sell 14
- thread go sell 13
- thread run sell 12
- thread go sell 11
- thread go sell 10
- thread run sell 9
- thread go sell 8
- thread run sell 7
- thread go sell 6
- thread go sell 5
- thread run sell 4
- thread go sell 3
- thread run sell 2
- thread run sell 1
- name is zhycheng,and age is 23,sex is male
- delete data
- thread run sell 100
- thread run sell 99
- thread go sell 98
- thread go sell 97
- thread run sell 96
- thread go sell 95
- thread go sell 94
- thread run sell 93
- thread go sell 92
- thread run sell 91
- thread go sell 90
- thread go sell 89
- thread run sell 88
- thread go sell 87
- thread run sell 86
- thread go sell 85
- thread run sell 84
- thread go sell 83
- thread run sell 82
- thread go sell 81
- thread run sell 80
- thread go sell 79
- thread run sell 78
- thread go sell 77
- thread run sell 76
- thread go sell 75
- thread run sell 74
- thread go sell 73
- thread run sell 72
- thread go sell 71
- thread run sell 70
- thread go sell 69
- thread go sell 68
- thread run sell 67
- thread go sell 66
- thread run sell 65
- thread go sell 64
- thread run sell 63
- thread go sell 62
- thread run sell 61
- thread go sell 60
- thread run sell 59
- thread go sell 58
- thread run sell 57
- thread go sell 56
- thread run sell 55
- thread go sell 54
- thread run sell 53
- thread run sell 52
- thread go sell 51
- thread run sell 50
- thread go sell 49
- thread run sell 48
- thread go sell 47
- thread run sell 46
- thread go sell 45
- thread run sell 44
- thread run sell 43
- thread go sell 42
- thread run sell 41
- thread run sell 40
- thread go sell 39
- thread run sell 38
- thread run sell 37
- thread run sell 36
- thread run sell 35
- thread go sell 34
- thread run sell 33
- thread run sell 32
- thread go sell 31
- thread run sell 30
- thread run sell 29
- thread run sell 28
- thread run sell 27
- thread run sell 26
- thread run sell 25
- thread go sell 24
- thread run sell 23
- thread go sell 22
- thread go sell 21
- thread run sell 20
- thread go sell 19
- thread run sell 18
- thread run sell 17
- thread go sell 16
- thread run sell 15
- thread go sell 14
- thread go sell 13
- thread run sell 12
- thread go sell 11
- thread go sell 10
- thread run sell 9
- thread go sell 8
- thread run sell 7
- thread go sell 6
- thread go sell 5
- thread run sell 4
- thread go sell 3
- thread run sell 2
- thread run sell 1
可以看到,这个打印结果正确无误。如果不加mutex会是什么样的结果呢,我将线程同步的mutex注释掉,输出的结果为:
- name is zhycheng,and age is 23,sex is male
- delete data
- thread run sell 100
- thread run sell 99
- thread run sell 98
- thread go sell 97
- thread run sell 96
- thread go sell 95
- thread run sell 94
- thread go sell 94
- thread run sell 92
- thread run sell 91
- thread go sell 90
- thread run sell 89
- thread go sell 88
- thread run sell 87
- thread run sell 86
- thread go sell 86
- thread go sell 84
- thread run sell 83
- thread go sell 82
- thread run sell 81
- thread go sell 80
- thread run sell 79
- thread run sell 78
- thread go sell 77
- thread run sell 76
- thread run sell 75
- thread go sell 74
- thread run sell 73
- thread go sell 72
- thread run sell 71
- thread go sell 70
- thread go sell 69
- thread run sell 68
- thread go sell 67
- thread go sell 66
- thread run sell 65
- thread go sell 64
- thread go sell 63
- thread run sell 62
- thread go sell 61
- thread run sell 60
- thread run sell 59
- thread run sell 58
- thread run sell 57
- thread run sell 56
- thread run sell 55
- thread go sell 54
- thread run sell 54
- thread go sell 52
- thread run sell 52
- thread go sell 50
- thread run sell 50
- thread go sell 49
- thread run sell 47
- thread go sell 47
- thread go sell 45
- thread run sell 45
- thread run sell 43thread go sell 43
- thread run sell 41
- thread go sell 41
- thread go sell 39
- thread run sell 39
- thread run sell 37
- thread go sell 37
- thread go sell 35
- thread run sell 35
- thread go sell 33thread run sell 33
- thread go sell 31thread run sell 31
- thread go sell 29
- thread run sell 29
- thread go sell 27
- thread run sell 27
- thread go sell 25
- thread run sell 25
- thread run sell 23
- thread go sell 23
- thread run sell 21
- thread go sell 21
- thread go sell 19
- thread run sell 19
- thread run sell 17
- thread go sell 17
- thread go sell 15
- thread run sell 15
- thread run sell 13
- thread go sell 13
- thread run sell 11thread go sell 11
- thread go sell 9
- thread run sell 9
- thread run sell 7
- thread go sell 7
- thread go sell 5thread run sell 5
- thread go sell 3
- thread run sell 3
- thread go sell 1
- thread run sell 1
- name is zhycheng,and age is 23,sex is male
- delete data
- thread run sell 100
- thread run sell 99
- thread run sell 98
- thread go sell 97
- thread run sell 96
- thread go sell 95
- thread run sell 94
- thread go sell 94
- thread run sell 92
- thread run sell 91
- thread go sell 90
- thread run sell 89
- thread go sell 88
- thread run sell 87
- thread run sell 86
- thread go sell 86
- thread go sell 84
- thread run sell 83
- thread go sell 82
- thread run sell 81
- thread go sell 80
- thread run sell 79
- thread run sell 78
- thread go sell 77
- thread run sell 76
- thread run sell 75
- thread go sell 74
- thread run sell 73
- thread go sell 72
- thread run sell 71
- thread go sell 70
- thread go sell 69
- thread run sell 68
- thread go sell 67
- thread go sell 66
- thread run sell 65
- thread go sell 64
- thread go sell 63
- thread run sell 62
- thread go sell 61
- thread run sell 60
- thread run sell 59
- thread run sell 58
- thread run sell 57
- thread run sell 56
- thread run sell 55
- thread go sell 54
- thread run sell 54
- thread go sell 52
- thread run sell 52
- thread go sell 50
- thread run sell 50
- thread go sell 49
- thread run sell 47
- thread go sell 47
- thread go sell 45
- thread run sell 45
- thread run sell 43thread go sell 43
- thread run sell 41
- thread go sell 41
- thread go sell 39
- thread run sell 39
- thread run sell 37
- thread go sell 37
- thread go sell 35
- thread run sell 35
- thread go sell 33thread run sell 33
- thread go sell 31thread run sell 31
- thread go sell 29
- thread run sell 29
- thread go sell 27
- thread run sell 27
- thread go sell 25
- thread run sell 25
- thread run sell 23
- thread go sell 23
- thread run sell 21
- thread go sell 21
- thread go sell 19
- thread run sell 19
- thread run sell 17
- thread go sell 17
- thread go sell 15
- thread run sell 15
- thread run sell 13
- thread go sell 13
- thread run sell 11thread go sell 11
- thread go sell 9
- thread run sell 9
- thread run sell 7
- thread go sell 7
- thread go sell 5thread run sell 5
- thread go sell 3
- thread run sell 3
- thread go sell 1
- thread run sell 1
可以看到,有的票卖了两次,有的票就没卖。
4.注意
1.Sleep()函数是使得线程休眠的函数,这个函数不跨平台,仅仅在windows上能用,其他平台使用usleep。
然后就去看了CCAutoreleasePool的源码,发现存在Cocos2d-X的内存管理在多线程的情况下存在如下问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
//-------------------------------------------------------------------- // // CCPoolManager // //-------------------------------------------------------------------- /【diff - begin】- by layne// CCPoolManager* CCPoolManager::sharedPoolManager() { if (s_pPoolManager == NULL) { s_pPoolManager = new CCPoolManager(); } return s_pPoolManager; } void CCPoolManager::purgePoolManager() { CC_SAFE_DELETE(s_pPoolManager); } CCPoolManager::CCPoolManager() { // m_pReleasePoolStack = new CCArray(); // m_pReleasePoolStack->init(); // m_pCurReleasePool = 0; m_pReleasePoolMultiStack = new CCDictionary(); } CCPoolManager::~CCPoolManager() { // finalize(); // // we only release the last autorelease pool here // m_pCurReleasePool = 0; // m_pReleasePoolStack->removeObjectAtIndex(0); // // CC_SAFE_DELETE(m_pReleasePoolStack); finalize(); CC_SAFE_DELETE(m_pReleasePoolMultiStack); } void CCPoolManager::finalize() { if(m_pReleasePoolMultiStack->count() > 0) { //CCAutoreleasePool* pReleasePool; CCObject* pkey = NULL; CCARRAY_FOREACH(m_pReleasePoolMultiStack->allKeys(), pkey) { if(!pkey) break; CCInteger *key = (CCInteger*)pkey; CCArray *poolStack = (CCArray *)m_pReleasePoolMultiStack->objectForKey(key->getValue()); CCObject* pObj = NULL; CCARRAY_FOREACH(poolStack, pObj) { if(!pObj) break; CCAutoreleasePool* pPool = (CCAutoreleasePool*)pObj; pPool->clear(); } } } } void CCPoolManager::push() { // CCAutoreleasePool* pPool = new CCAutoreleasePool(); //ref = 1 // m_pCurReleasePool = pPool; // // m_pReleasePoolStack->addObject(pPool); //ref = 2 // // pPool->release(); //ref = 1 pthread_mutex_lock(&m_mutex); CCArray* pCurReleasePoolStack = getCurReleasePoolStack(); CCAutoreleasePool* pPool = new CCAutoreleasePool(); //ref = 1 pCurReleasePoolStack->addObject(pPool); //ref = 2 pPool->release(); //ref = 1 pthread_mutex_unlock(&m_mutex); } void CCPoolManager::pop() { // if (! m_pCurReleasePool) // { // return; // } // // int nCount = m_pReleasePoolStack->count(); // // m_pCurReleasePool->clear(); // // if(nCount > 1) // { // m_pReleasePoolStack->removeObjectAtIndex(nCount-1); // // // if(nCount > 1) // // { // // m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2); // // return; // // } // m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2); // } // // /*m_pCurReleasePool = NULL;*/ pthread_mutex_lock(&m_mutex); CCArray* pCurReleasePoolStack = getCurReleasePoolStack(); CCAutoreleasePool* pCurReleasePool = getCurReleasePool(); if (pCurReleasePoolStack && pCurReleasePool) { int nCount = pCurReleasePoolStack->count(); pCurReleasePool->clear(); if(nCount > 1) { pCurReleasePoolStack->removeObject(pCurReleasePool); } } pthread_mutex_unlock(&m_mutex); } void CCPoolManager::removeObject(CCObject* pObject) { // CCAssert(m_pCurReleasePool, "current auto release pool should not be null"); // // m_pCurReleasePool->removeObject(pObject); pthread_mutex_lock(&m_mutex); CCAutoreleasePool* pCurReleasePool = getCurReleasePool(); CCAssert(pCurReleasePool, "current auto release pool should not be null"); pCurReleasePool->removeObject(pObject); pthread_mutex_unlock(&m_mutex); } void CCPoolManager::addObject(CCObject* pObject) { // getCurReleasePool()->addObject(pObject); pthread_mutex_lock(&m_mutex); CCAutoreleasePool* pCurReleasePool = getCurReleasePool(true); CCAssert(pCurReleasePool, "current auto release pool should not be null"); pCurReleasePool->addObject(pObject); pthread_mutex_unlock(&m_mutex); } CCArray* CCPoolManager::getCurReleasePoolStack() { CCArray* pPoolStack = NULL; pthread_t tid = pthread_self(); if(m_pReleasePoolMultiStack->count() > 0) { pPoolStack = (CCArray*)m_pReleasePoolMultiStack->objectForKey((int)tid); } if (!pPoolStack) { pPoolStack = new CCArray(); m_pReleasePoolMultiStack->setObject(pPoolStack, (int)tid); pPoolStack->release(); } return pPoolStack; } CCAutoreleasePool* CCPoolManager::getCurReleasePool(bool autoCreate) { // if(!m_pCurReleasePool) // { // push(); // } // // CCAssert(m_pCurReleasePool, "current auto release pool should not be null"); // // return m_pCurReleasePool; CCAutoreleasePool* pReleasePool = NULL; CCArray* pPoolStack = getCurReleasePoolStack(); if(pPoolStack->count() > 0) { pReleasePool = (CCAutoreleasePool*)pPoolStack->lastObject(); } if (!pReleasePool && autoCreate) { CCAutoreleasePool* pPool = new CCAutoreleasePool(); //ref = 1 pPoolStack->addObject(pPool); //ref = 2 pPool->release(); //ref = 1 pReleasePool = pPool; } return pReleasePool; } /【diff - end】- by layne// 代码下载地址:https://github.com/kaitiren/pthread-test-for-cocos2dx |
cocos2dx多线程以及线程同步 与 cocos2dx内存管理与多线程问题相关推荐
- cocos2dx多线程以及线程同步 与 cocos2dx内存管理与多线程问题
cocos2d-x引擎在内部实现了一个庞大的主循环,每帧之间更新界面,如果耗时的操作放到了主线程中,游戏的界面就会卡,这是不能容忍的,游戏最基本的条件就是流畅性,这就是为什么游戏开发选择C++的原因. ...
- 3、Linux多线程,线程同步(转)
3.Linux多线程,线程同步 5)线程私有数据 进程内的所有线程共享进程的数据空间,因此全局变量为所有线程所共有.但有时线程也需要保存自己的私有数据,这时可以创建线程私有数据(Thread-spec ...
- Java 多线程和线程同步总结
转载:JAVA多线程实现和线程同步总结 1.JAVA多线程实现方式 JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable ...
- VC++ MFC 多线程及线程同步(详细、全面总结!)
更多详情:http://blog.csdn.net/whyacinth/ VC++ MFC 多线程及线程同步 关键词: MFC 多线程及线程同步 ...
- Java多线程之线程同步机制(锁,线程池等等)
Java多线程之线程同步机制 一.概念 1.并发 2.起因 3.缺点 二.三大不安全案例 1.样例一(模拟买票场景) 2.样例二(模拟取钱场景) 3.样例三(模拟集合) 三.同步方法及同步块 1.同步 ...
- C#笔记20:多线程之线程同步中的信号量AutoResetEvent和ManualResetEvent
C#笔记20:多线程之线程同步中的信号量AutoResetEvent和ManualResetEvent 本章概要: 1:终止状态和非终止状态 2:AutoResetEvent和ManualResetE ...
- MFC 多线程及线程同步
一.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常 ...
- 【Java 并发编程】多线程、线程同步、死锁、线程间通信(生产者消费者模型)、可重入锁、线程池
并发编程(Concurrent Programming) 进程(Process).线程(Thread).线程的串行 多线程 多线程的原理 多线程的优缺点 Java并发编程 默认线程 开启新线程 `Ru ...
- java多线程:线程同步synchronized(不同步的问题、队列与锁),死锁的产生和解决
0.不同步的问题 并发的线程不安全问题: 多个线程同时操作同一个对象,如果控制不好,就会产生问题,叫做线程不安全. 我们来看三个比较经典的案例来说明线程不安全的问题. 0.1 订票问题 例如前面说过的 ...
最新文章
- TVM自定义数据类型
- Matlab中的lsqcurvefit函数的使用
- 模拟键盘输入的keycode
- mysql安装start service错误_为什么安装mysql会出现start service错误
- 1、leetcode437 路和总径3
- codevs 1269 匈牙利游戏
- poi报空指针_POI 导出文件 报空指针异常 --Docker 中
- ABP vNext微服务架构详细教程——分布式权限框架(下)
- python-函数的闭包
- “梅丽莎”病毒背后的神秘黑客
- Instagram: 用Django服务30亿用户
- 计算机手速专业说法,大学里“挂科率超高”的专业,学霸也不好拿捏,考试难补考更难...
- matlab圆形数据集,Matlab处理SPEI全球数据集
- PcShare2007 暗桩
- 我的世界java版怎么打开游戏菜单_我的世界游戏界面设置方法
- Android实现随意拖动View效果
- oracle的em能干什么,Oracle中EM的配置
- 金彩教育:提升产品标签的方法
- 用计算机发送电子邮件,用英语解释一下发送电子邮件的过程 用计算机语言来说一下,大概400到500个英文单词...
- 基于PID控制的电机速度闭环控制系统演示和讲解