翻转队列的实现

        在多线程中,经常会出现这样一种模式,A线程向队列L中push元素,B线程从队列L中pop元素,为了线程安全,必须在A push的时候加锁,然后在B pop的时候也加锁,这是一个典型的生产者消费者模式,这样显然会降低程序的效率。那么怎样来优化这种情景呢?

        我们可以使用翻转队列(又称交换队列)来提高这个模型的效率,设计思想是使用2个队列L1,L2,A还是继续向L1中push元素,但是B从L2中pop元素,然后当L2为空的时候,交换L1和L2,这样,A push的时候还是需要加锁,但是B pop的时候就不用加锁,只需要在交换L1和L2的时候加锁,真正产生冲突只有在交换的时候。这样就极大的减少锁互斥的几率,优化了模型的效率。

        代码如下(加锁的代码为伪代码),使用模板实现:

template<typename _OBJ>
class SwappingList
{
public:
	size_t Add(_OBJ & obj )
	{
		ResGuard<Mutex> lock(m_frontMutex);
		m_frontList->push_back(obj);
		return m_frontList->size();
	}
 
	bool Get(_OBJ & obj )
	{
		if ( m_backList->empty() )
		{
			Swap();
		}
		if ( m_backList->empty() )
		{
			return false;
		}
		obj = m_backList->front();
		m_backList->pop_front();
		return true;
	}
 
	void Swap()
	{
		ResGuard<Mutex> lock(m_frontMutex);
		PRODUCT_LIST * p = m_backList;
		m_backList = m_frontList;
		m_frontList = p;
	}
 
	SwappingList()
	{
		m_frontList = new PRODUCT_LIST;
		m_backList  = new PRODUCT_LIST;
	}
 
	virtual ~SwappingList()
	{
		if ( m_frontList )
		{
			delete m_frontList;
			m_frontList = 0;
		}
		if ( m_backList )
		{
			delete m_backList;
			m_backList = 0;
		}
	}
 
protected:
	typedef std::list<_OBJ>   PRODUCT_LIST;
	PRODUCT_LIST*        m_frontList;
	PRODUCT_LIST*        m_backList;
	Mutex                m_frontMutex;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Seebug漏洞平台

从WordPress SQLi谈PHP格式化字符串问题

近日,WordPress爆出了一个SQLi漏洞,漏洞发生在WP的后台上传图片的位置,通过修改图片在数据库中的参数,以及利用php的sprintf函数的特性,在删...

433110
来自专栏用户画像

JAVA单例模式

在整个应用中,保证一个类只有一个实例,它提供了一个可以访问到它自己的全局访问点(静态方法)。

11820
来自专栏专注 Java 基础分享

初识Hibernate之继承映射

     前面的两篇文章中,我们介绍了两张表之间的各种相互关联映射关系,但往往我们也会遇到两张表甚至多张表之间共有着多个相同的字段。例如: ? 如图,stude...

19980
来自专栏Hongten

spring开发_Spring+Struts2

http://www.cnblogs.com/hongten/gallery/image/112920.html

10920
来自专栏芋道源码1024

【死磕Java并发】—–Java内存模型之从JMM角度分析DCL

DCL,即Double Check Lock,中卫双重检查锁定。其实DCL很多人在单例模式中用过,LZ面试人的时候也要他们写过,但是有很多人都会写错。他们为什么...

377120
来自专栏听雨堂

Python防止sql注入

看了网上文章,说的都挺好的,给cursor.execute传递格式串和参数,就能防止注入,但是我写了代码,却死活跑不通,怀疑自己用了一个假的python 最后,...

42270
来自专栏帘卷西风的专栏

关于mysql自增id的获取和重置

转载请注明出处:帘卷西风的专栏(http://blog.csdn.net/ljxfblog)

63220
来自专栏智能合约

Phalcon入门教程之模型CURD(1)

17520
来自专栏运维咖啡吧

Django model select的各种用法详解

Q对象可以对关键字参数进行封装,从而更好的应用多个查询,可以组合&(and)、|(or)、~(not)操作符。

12930
来自专栏Java成长之路

单例模式

所谓饿汉式单例设计模式,就是将类的静态实例作为该类的一个成员变量,也就是说在JVM 加载它的时候就已经创建了该类的实例,因此它不会存在多线程的安全问题。

11730

扫码关注云+社区

领取腾讯云代金券