当前位置: 首页 > news >正文

如何做网站充值三把火科技网站设计

如何做网站充值,三把火科技网站设计,深圳开发公司网站建设比较好的,wordpress网站微信登录单例模式是什么 在一个项目中#xff0c;全局范围内#xff0c;某个类的实例有且仅有一个#xff08;只能new一次#xff09;#xff0c;通过这个唯一的实例向其他模块提供数据的全局访问#xff0c;这种模式就叫单例模式。单例模式的典型应用就是任务队列。 为什么要使…单例模式是什么 在一个项目中全局范围内某个类的实例有且仅有一个只能new一次通过这个唯一的实例向其他模块提供数据的全局访问这种模式就叫单例模式。单例模式的典型应用就是任务队列。 为什么要使用单例模式 单例模式充当的就是一个全局变量为什么不直接使用全局变量呢因为全局变量破坏类的封装而且不受保护访问不受限制。 饿汉模式 饿汉模式是在类加载时进行实例化的。 #includeiostream using namespace std;class TaskQueue { public:TaskQueue(const TaskQueue obj) delete;//禁用拷贝构造TaskQueue operator (const TaskQueue obj) delete;//禁用赋值构造static TaskQueue* getInstance() //获取单例的方法{cout 我是一个饿汉模式单例 endl;return m_taskQ;}private:TaskQueue() default; //无参构造static TaskQueue* m_taskQ; //静态成员需要在类外定义 }; TaskQueue* TaskQueue::m_taskQ new TaskQueue;//new一个实例int main() {TaskQueue* obj TaskQueue::getInstance(); }懒汉模式 懒汉模式是在需要使用的时候再进行实例化 #includeiostream using namespace std;class TaskQueue { public:TaskQueue(const TaskQueue obj) delete;//禁用拷贝构造TaskQueue operator (const TaskQueue obj) delete;//禁用赋值构造static TaskQueue* getInstance() //获取单例的方法{if (nullptr m_taskQ){m_taskQ new TaskQueue;}return m_taskQ;}private:TaskQueue() default; //无参构造static TaskQueue* m_taskQ; //静态成员需要在类外定义 }; TaskQueue* TaskQueue::m_taskQ nullptr;int main() {TaskQueue* obj TaskQueue::getInstance(); }在调用**getInstance()**函数获取单例对象的时候如果在单线程情况下是没有什么问题的如果是多个线程调用这个函数去访问单例对象就有问题了。假设有三个线程同时执行了getInstance()函数在这个函数内部每个线程都会new出一个实例对象。此时这个任务队列类的实例对象不是一个而是3个很显然这与单例模式的定义是相悖的。 线程安全问题 对于饿汉模式来说是没有线程安全问题的在这种模式下访问单例对象时这个对象已经被创建出来了要解决懒汉模式的线程安全问题最常用的解决方案就是使用互斥锁可以将创建单例对象的代码使用互斥锁锁住 #includeiostream #includemutex using namespace std;class TaskQueue { public:TaskQueue(const TaskQueue obj) delete;//禁用拷贝构造TaskQueue operator (const TaskQueue obj) delete;//禁用赋值构造static TaskQueue* getInstance() //获取单例的方法{m_mutex.lock();if (nullptr m_taskQ){cout 我加了互斥锁 endl;m_taskQ new TaskQueue;}m_mutex.unlock();return m_taskQ;}private:TaskQueue() default; //无参构造static TaskQueue* m_taskQ; //静态成员需要在类外定义static mutex m_mutex; //定义为静态的因为静态函数只能使用静态变量 }; mutex TaskQueue::m_mutex; TaskQueue* TaskQueue::m_taskQ nullptr;int main() {TaskQueue* obj TaskQueue::getInstance(); }在上面代码的10~13 行这个代码块被互斥锁锁住了也就意味着不论有多少个线程同时执行这个代码块的线程只能是一个相当于是严重限行了在重负载情况下可能导致响应缓慢。我们可以将代码再优化一下 #includeiostream #includemutex using namespace std;class TaskQueue { public:TaskQueue(const TaskQueue obj) delete;//禁用拷贝构造TaskQueue operator (const TaskQueue obj) delete;//禁用赋值构造static TaskQueue* getInstance() //获取单例的方法{if (nullptr m_taskQ){m_mutex.lock();if (nullptr m_taskQ){cout 我加了互斥锁 endl;m_taskQ new TaskQueue;}m_mutex.unlock();}return m_taskQ;}private:TaskQueue() default; //无参构造static TaskQueue* m_taskQ; //静态成员需要在类外定义static mutex m_mutex; }; mutex TaskQueue::m_mutex; TaskQueue* TaskQueue::m_taskQ nullptr;int main() {TaskQueue* obj TaskQueue::getInstance(); }双重检查锁定问题 #includeiostream #includemutex #includeatomic using namespace std;class TaskQueue { public:TaskQueue(const TaskQueue obj) delete;//禁用拷贝构造TaskQueue operator (const TaskQueue obj) delete;//禁用赋值构造static TaskQueue* getInstance() //获取单例的方法{TaskQueue* taskQ m_taskQ.load(); //取出来单例的值if (nullptr taskQ){m_mutex.lock();taskQ m_taskQ.load();if (nullptr taskQ){cout 我加了原子 endl;taskQ new TaskQueue;m_taskQ.store(taskQ); //保存到原子变量中}m_mutex.unlock();}return m_taskQ.load();}private:TaskQueue() default; //无参构造static atomicTaskQueue*m_taskQ; //定义为原子变量static mutex m_mutex; }; mutex TaskQueue::m_mutex; atomicTaskQueue* TaskQueue::m_taskQ;int main() {TaskQueue* obj TaskQueue::getInstance(); }对于m_taskQ new TaskQueue这行代码来说我们期望的执行机器指令执行顺序是 1分配用来保存TaskQueue对象的内存 2在分配好的内存中构造一个TaskQueue对象即初始化内存 3使用m_taskQ指针指向分配的内存。 但是对多线程来说机器指令可能会被重新排列即 1分配内存用于保存 TaskQueue 对象。 2使用 m_taskQ 指针指向分配的内存。 3在分配的内存中构造一个 TaskQueue 对象初始化内存。 这样重排序并不影响单线程的执行结果但是在多线程中就会出问题。如果线程A按照第二种顺序执行机器指令执行完前两步之后失去CPU时间片被挂起了此时线程B在第3行处进行指针判断的时候m_taskQ 指针是不为空的但这个指针指向的内存却没有被初始化最后线程 B 使用了一个没有被初始化的队列对象就出问题了出现这种情况是概率问题需要反复的大量测试问题才可能会出现。 在C11中引入了原子变量atomic通过原子变量可以实现一种更安全的懒汉模式的单例代码如下 #includeiostream #includemutex #includeatomic using namespace std;class TaskQueue { public:TaskQueue(const TaskQueue obj) delete;//禁用拷贝构造TaskQueue operator (const TaskQueue obj) delete;//禁用赋值构造static TaskQueue* getInstance() //获取单例的方法{TaskQueue* taskQ m_taskQ.load(); //取出来单例的值if (nullptr taskQ){m_mutex.lock();taskQ m_taskQ.load();if (nullptr taskQ){cout 我加了原子 endl;taskQ new TaskQueue;m_taskQ.store(taskQ); //保存到原子变量中}m_mutex.unlock();}return m_taskQ.load();}private:TaskQueue() default; //无参构造static atomicTaskQueue*m_taskQ; //定义为原子变量static mutex m_mutex; }; mutex TaskQueue::m_mutex; atomicTaskQueue* TaskQueue::m_taskQ;int main() {TaskQueue* obj TaskQueue::getInstance(); }使用局部静态 c11新特性有如下规定如果指令逻辑进入一个未被初始化的声明标量所有并发执行应当等待该变量完成初始化。 #includeiostreamusing namespace std;class TaskQueue { public:TaskQueue(const TaskQueue obj) delete;//禁用拷贝构造TaskQueue operator (const TaskQueue obj) delete;//禁用赋值构造static TaskQueue* getInstance() //获取单例的方法{static TaskQueue m_taskQ; //未被初始化return m_taskQ;}void print(){cout hello, world!!! endl;}private:TaskQueue() default; //无参构造 };int main() {TaskQueue* obj TaskQueue::getInstance();obj-print(); }饿汉模式和懒汉模式的区别 懒汉模式的缺点是在创建实例对象的时候有安全问题但这样可以减少内存的浪费如果用不到就不去申请内存了。饿汉模式则相反在我们不需要这个实例对象的时候它已经被创建出来占用了一块内存。对于现在的计算机而言内存容量都是足够大的这个缺陷可以被无视。
http://www.yutouwan.com/news/257652/

相关文章:

  • 英文网站模版书画网站模板
  • 湖北正规网站建设检修十大网游人气排行榜
  • 网站开发外包 验收17网一起做网店下载
  • 网站开发技术试验总结徐州个人建站模板
  • 设计网站首页多少钱郑州网站建设索q479185700
  • 1g做网站空间佛山市城乡住房建设局网站
  • 怎样上传自己做的网站蓬莱做网站那家好
  • 一般网站服务器配置网站空间速度快
  • 广西钦州网站建设做游戏直播什么游戏视频网站好
  • jquery 素材的网站游戏开发工程师需要学什么
  • 人才网站什么创网站
  • 做网站主播要什么条件网站怎么留住用户
  • 苏州实力做网站公司国内外优秀建筑设计网站
  • wordpress建站如何制作微信会员发布网站建设
  • 二手网站设计与建设人力资源外包服务包括哪些
  • 可以发锚文本的网站花卉电子商务网站开发
  • 简洁大气的网站推荐国外免费域名网站
  • 网站查询站长工具建筑网校排名前十大品牌
  • 湖州长兴县建设局网站做普通网站价格
  • 大学网站设计在中国做国外网站
  • 制作公司网站用什么软件烟台网站建设优惠臻动传媒
  • 网站一键提交收录政务网的门户网站建设
  • 合肥网站 技术支持 上诚科技网站建设找至尚网络
  • 网站建设与维护面试洛阳做网站公司地址
  • 聊城网站建设公司网站开发使用api对seo
  • 青岛建站推广整合营销传播的定义
  • 外国人学做中国菜 网站沈阳今天重大新闻
  • 做城市分类信息网站好做吗深圳网站维护有限公司
  • 网站开发研究前景 论文网站推广途径和要点有哪些
  • 如何仿做别人的网站微九州合作网站