# encoding:utf-8

from collections import OrderedDict
from collections import MutableMapping
from threading import RLock

_Null = object()

def iterkeys(d, **kw):
return d.iterkeys(**kw)

def itervalues(d, **kw):
return d.itervalues(**kw)

class RecentlyUsedContainer(MutableMapping):
"""
Provides a thread-safe dict-like container which maintains up to
``maxsize`` keys while throwing away the least-recently-used keys beyond
``maxsize``.

:param maxsize:
Maximum number of recent elements to retain.

:param dispose_func:
Every time an item is evicted from the container,
``dispose_func(value)`` is called. Callback which will get called
"""

ContainerCls = OrderedDict

def __init__(self, maxsize=10, dispose_func=None):
self._maxsize = maxsize
self.dispose_func = dispose_func

self._container = self.ContainerCls()
self.lock = RLock()

def __getitem__(self, key):
# Re-insert the item, moving it to the end of the eviction line.
with self.lock:
item = self._container.pop(key)
self._container[key] = item
return item

def __setitem__(self, key, value):
evicted_value = _Null
with self.lock:
# Possibly evict the existing value of 'key'
evicted_value = self._container.get(key, _Null)
self._container[key] = value

# If we didn't evict an existing value, we might have to evict the
# least recently used item from the beginning of the container.
if len(self._container) > self._maxsize:
_key, evicted_value = self._container.popitem(last=False)

if self.dispose_func and evicted_value is not _Null:
self.dispose_func(evicted_value)

def __delitem__(self, key):
with self.lock:
value = self._container.pop(key)

if self.dispose_func:
self.dispose_func(value)

def __len__(self):
with self.lock:
return len(self._container)

def __iter__(self):
raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.')

def clear(self):
with self.lock:
# Copy pointers to all values, then wipe the mapping
values = list(itervalues(self._container))
print values
self._container.clear()

if self.dispose_func:
for value in values:
self.dispose_func(value)

def keys(self):
with self.lock:
return list(iterkeys(self._container))

if __name__ == '__main__':
d = RecentlyUsedContainer()
print(dir(d))
d['key1'] = 'value1'
print d._maxsize
# d['key2'] = 'value2'
# d['key3'] = 'value3'
# d['key4'] = 'value4'
# print d.keys()
# del d['key4']
# d.clear()
# print d.keys()

实现线程安全先进先出的dict的更多相关文章

  1. 07-SV线程以及线程间的通信

    1.几种语句块的区别 (1)fork……join:块内语句以并发方式执行 (2)begin……end:块内语句以顺序方式执行 (3)fork……join_none:其块内语句执行时,父线程继续执行 ( ...

  2. 08_线程间通信 ITC

    1.线程间的通信方式 1.共享全局变量 2.线程队列(queue) 3.信号量(Semaphore) 2.共享全局变量进行通信 from threading import Thread import ...

  3. Python中的collections模块

    Python中内置了4种数据类型,包括:list,tuple,set,dict,这些数据类型都有其各自的特点,但是这些特点(比如dict无序)在一定程度上对数据类型的使用产生了约束,在某些使用场景下效 ...

  4. 廖雪峰Python电子书总结

    函数 1.注意:函数的默认参数必须指向不可变对象 未修改前: def add_end(L=[]): L.append('END') return L 存在的问题:如果连续调用多次,会出现多个 'END ...

  5. python基础--常用的模块(collections、time、datetime、random、os、sys、json、pickle)

    collection模块: namedtuple:它是一个函数,是用来创建一个自定义的tuple对象的,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素.所以我们就可以 ...

  6. step 4 GCD 队列演练

    串行队列 特点 以先进先出的方式,顺序调度队列中的任务执行 无论队列中所指定的执行任务函数是同步还是异步,都会等待前一个任务执行完成后,再调度后面的任务 队列创建 dispatch_queue_t q ...

  7. 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke

    今天关闭一个窗体,报出这样的一个错误"在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke.",这个不用多想,肯定是那个地方没有释放掉.既然碰到这个问题, ...

  8. 刀哥多线程之主队列gcd-06-main_queue

    主队列 特点 专门用来在主线程上调度任务的队列 不会开启线程 以先进先出的方式,在主线程空闲时才会调度队列中的任务在主线程执行 如果当前主线程正在有任务执行,那么无论主队列中当前被添加了什么任务,都不 ...

  9. iOS中你必须了解的多线程

    多线程概念详解 什么是进程? 简单的说进程就是我们电脑上运行的一个个应用程序,每一个程序就是一个进程,并且每个进程之间是独立的,每个进程运行在其专用受保护的内存空间内(window系统可以通过任务管理 ...

随机推荐

  1. canvas save()和canvas restore()状态的保存和恢复使用方法及实例

    canvas.save()用来保存先前状态的 canvas.restore()用来恢复之前保存的状态 注:两种方法必须搭配使用,否则没有效果 <!DOCTYPE html> <htm ...

  2. (三)Installation

    Elasticsearch requires at least Java 8. Specifically as of this writing, it is recommended that you ...

  3. 怎么在Vue的某个组件中根据组件tag标签名获取到对应的VueComponent实例呢

    1.以前玩omi框架的时候,有Omi.get方法来获取实例, ...好久没玩了,忘了.反正很喜欢该方法.2.如今想在vue里面怎么能够快速获取到对应组件标签名的的实例呢?3.文档也看过,似乎脑海中没啥 ...

  4. 横线和文字一排,文字居中显示vertical-align: middle;

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  5. Java实现动态修改Jar包内文件内容

    import java.io.*; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; ...

  6. .Net Core应用框架Util介绍(一)

    距离上次发文,已经过去了三年半,这几年技术更新节奏异常迅猛,.Net进入了跨平台时代,前端也被革命性的颠覆. 回顾 2015年,正当我还沉迷于JQuery + EasyUi的封装时,突然意识到技术已经 ...

  7. 基于 HTML5 的 WebGL 楼宇自控 3D 可视化监控

    前言 智慧楼宇和人们的生活息息相关,楼宇智能化程度的提高,会极大程度的改善人们的生活品质,在当前工业互联网大背景下受到很大关注.目前智慧楼宇可视化监控的主要优点包括: 智慧化 -- 智慧楼宇是一个生态 ...

  8. 本文详解5G是个什么鬼,程序员都准备好了吗?

    无线移动通讯发展历史 最近5G的概念炒的如火如荼,为此,华为和高通还干了一仗.这篇文章从技术层面给大家分析,什么是5G,它和4G比,高级在哪里? 我们来看看移动互联网的技术发展: 然后我们在来看看他们 ...

  9. SQL 无法连接服务器

    错误信息:provider:SQL Network Interfaces, error:52-无法定位 LOCA Database Runtime 安装.请验证SQL Server Express是否 ...

  10. Gradle构建Java工程配置详解