title author date CreateTime categories
C# dotnet 线程不安全的弱引用缓存
lindexi
2019-11-7 9:45:5 +0800
2019-11-06 16:58:11 +0800
dotnet C#

很多逻辑都会使用内存做缓存,这样可以提高运行效率。但是有一些逻辑很少会执行,但是如果有执行就是频繁调用。如我写了文本编辑器,在我打开文件的逻辑,将会不断调用正则判断逻辑,而平时编辑很少会调用。如果将这部分的正则逻辑缓存了,那么可以提升打开文件速度,但是在打开文件之后这部分就成为内存垃圾了。本文给大家一个弱引用缓存,也就是在频繁使用时从内存获取,在不使用时会被回收,这样可以提升性能也能减少内存使用

因为作为缓存,如果需要考虑线程安全,那么这部分的逻辑就复杂了。在不考虑线程安全下,开发一个弱引用缓存还是很简单

首先是创建一个字典,这个字典包含弱引用,这样在获取之前可以先从字典获取

        private readonly Dictionary<object, WeakReference<object>> _cacheList =
new Dictionary<object, WeakReference<object>>();

在用户获取之前,需要知道,可能内存回收了。所以使用方法是获取或创建,也就是这个方法不能保证只有第一次获取时才创建,而是看内存回收

 public T GetOrCreate<T>(object key, Func<T> createFunc)

如果此时可以从内存获取,那么直接返回

            if (_cacheList.TryGetValue(key, out var weakReference))
{
if (weakReference.TryGetTarget(out var value))
{
return (T) value;
}
}

如果不能从内存获取,就需要调用方法创建

            var t = createFunc();
weakReference = new WeakReference<object>(t);
_cacheList[key] = weakReference;
return t;

所以获取方法如下

        /// <summary>
/// 从缓存获取或在没有获取到创建
/// </summary>
public T GetOrCreate<T>(object key, Func<T> createFunc)
{
if (_cacheList.TryGetValue(key, out var weakReference))
{
if (weakReference.TryGetTarget(out var value))
{
return (T) value;
}
} var t = createFunc();
weakReference = new WeakReference<object>(t);
_cacheList[key] = weakReference;
return t;
}

因为每次给一个 key 也不好用,有一些对象只需要一个类只有存在一个,可以使用类型作为 key 可以再写另一个方法

        /// <summary>
/// 从缓存获取或在没有获取到创建
/// </summary>
public T GetOrCreate<T>(Func<T> createFunc)
{
var type = typeof(T);
return GetOrCreate(type, createFunc);
}

这个线程不安全的弱引用缓存所有代码很少,可以直接复制在项目使用

    /// <summary>
/// 弱引用缓存
/// </summary>
public class WeakReferenceCache
{
/// <summary>
/// 从缓存获取或在没有获取到创建
/// </summary>
public T GetOrCreate<T>(object key, Func<T> createFunc)
{
if (_cacheList.TryGetValue(key, out var weakReference))
{
if (weakReference.TryGetTarget(out var value))
{
return (T) value;
}
} var t = createFunc();
weakReference = new WeakReference<object>(t);
_cacheList[key] = weakReference;
return t;
} /// <summary>
/// 从缓存获取或在没有获取到创建
/// </summary>
public T GetOrCreate<T>(Func<T> createFunc)
{
var type = typeof(T);
return GetOrCreate(type, createFunc);
} private readonly Dictionary<object, WeakReference<object>> _cacheList =
new Dictionary<object, WeakReference<object>>();
}

此方法是线程不安全的,请不要在多线程下使用此方法,可以通过 线程静态字段 让一个线程有一个实例

本文代码放在 github 欢迎小伙伴访问

最新文章

  1. H5 canvas的 width、height 与style中宽高的区别
  2. ASP.NET MVC Model绑定(二)
  3. web.xml中url-pattern的用法
  4. Node.js、express、mongodb 入门(基于easyui datagrid增删改查)
  5. java-集合1
  6. jQuery 判断页面元素是否存在的代码
  7. JAVA 1.9 面向对象之封装
  8. 计算std:string的字节长度
  9. CSS2-3常见的demo列子总结
  10. PHP获取服务器的mac地址类
  11. (转)Eclipse中自动添加注释(作者,时间)
  12. Redis进阶实践之十 Redis哨兵集群模式
  13. Java finalize方法使用
  14. TMS-规划图
  15. Luogu P3868 [TJOI2009]猜数字
  16. Announcing WebKit SDL port
  17. C# 图像处理:实现鼠标选择矩形截图
  18. 通过DataTable获得表的主键
  19. .NET 开源GIS项目
  20. mysql 数据类型TIMESTAMP用法

热门文章

  1. hive中的lateral view 与 explode函数的使用
  2. NX二次开发-清除信息窗口中的内容,退出信息窗口UF_UI_exit_listing_window
  3. 秦曾昌人工智能课程---5、KNN和朴素贝叶斯
  4. jvm-多线程
  5. 【转】Linux(CentOS) vps安装xfce桌面+VNC
  6. Codeforces 166B - Polygon (判断凸包位置关系)
  7. [21]APUE:线程同步之记录锁(文件)
  8. man命令的使用方法
  9. 《转》python 11 表达式和语句
  10. Milking Cows /// 区间计数 离散化排序 oj10105