缓存与锁:让你的Python代码不仅能飞且安全

什么是缓存?

缓存(Cache)就是把一些耗时的计算结果存起来,下次再用的时候直接拿出来,不用再重新计算。就像你去超市买东西,第一次找货架找得头晕眼花,第二次直接去你记得的地方拿就好了。

为什么要用锁?

在多线程环境中,多个线程可能同时访问和修改缓存,这时候就需要锁(Lock)来确保线程安全。锁就像是超市的保安,确保每次只有一个人能拿货,避免混乱。

cachetools 的 cachedmethod 和 lock

cachetools 是一个强大的缓存库,提供了多种缓存策略。我们今天要用的是 cachedmethod 和 TTLCache,再加上 threading.Lock 来确保线程安全。

实战演练

话不多说,直接上代码!

python 复制代码
import threading
from cachetools import cachedmethod, TTLCache
from cachetools.keys import hashkey

class ExpensiveComputation:
    def __init__(self):
        # 创建一个 TTLCache 对象,设置最大容量为 100,TTL(Time To Live)为 300 秒
        self.cache = TTLCache(maxsize=100, ttl=300)
        # 创建一个锁对象
        self.lock = threading.Lock()

    @cachedmethod(cache=lambda self: self.cache, key=hashkey, lock=lambda self: self.lock)
    def compute(self, x):
        print(f"Computing {x}...")
        return x * x

# 多线程环境下调用
def worker(obj, n):
    print(f"Result for {n}: {obj.compute(n)}")

expensive_computation = ExpensiveComputation()

threads = []
for i in range(5):
    t = threading.Thread(target=worker, args=(expensive_computation, i))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

代码解析

  1. 创建缓存对象和锁对象:
python 复制代码
class ExpensiveComputation:
    def __init__(self):
        self.cache = TTLCache(maxsize=100, ttl=300)
        self.lock = threading.Lock()

在类的构造函数中,我们创建了一个 TTLCache 对象和一个 threading.Lock 对象。TTLCache 的最大容量是 100,缓存项的生存时间是 300 秒。

  1. 使用 cachedmethod 装饰器:
python 复制代码
@cachedmethod(cache=lambda self: self.cache, key=hashkey, lock=lambda self: self.lock)
def compute(self, x):
    print(f"Computing {x}...")
    return x * x

使用 cachedmethod 装饰器装饰 compute 方法,并传入 cache 和 lock 参数。cache 参数使用 lambda self: self.cache 形式,以便在实例方法中访问实例属性。lock 参数同样使用 lambda self: self.lock 形式。

  1. 多线程调用:
python 复制代码
def worker(obj, n):
    print(f"Result for {n}: {obj.compute(n)}")

expensive_computation = ExpensiveComputation()

threads = []
for i in range(5):
    t = threading.Thread(target=worker, args=(expensive_computation, i))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

创建多个线程并调用 compute 方法,验证缓存的线程安全性。

总结:

通过结合 cachetools 的 cachedmethod 装饰器、TTLCache 和 threading.Lock,我们实现了线程安全且带有过期时间的类方法缓存。这样,你的代码不仅跑得更快,还能在多线程环境中稳如泰山。

相关推荐
qystca8 分钟前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法
薯条不要番茄酱8 分钟前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
今天吃饺子13 分钟前
2024年SCI一区最新改进优化算法——四参数自适应生长优化器,MATLAB代码免费获取...
开发语言·算法·matlab
努力进修17 分钟前
“探索Java List的无限可能:从基础到高级应用“
java·开发语言·list
不去幼儿园1 小时前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习
Ajiang28247353042 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
幽兰的天空2 小时前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
只因在人海中多看了你一眼3 小时前
分布式缓存 + 数据存储 + 消息队列知识体系
分布式·缓存
Dlwyz4 小时前
redis-击穿、穿透、雪崩
数据库·redis·缓存
Theodore_10225 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee