Cache存储引用类型

今天在单位写代码的时候,由于经常用到一组数据,变量类型为StringBuilder里面,为了提高速度,存储Cahche里面,结果每次变量存储在Cache以后,对变量的操作还会影响到Cache里面的变量的值,取出来以后还是改变的,觉得很奇怪,变量已经存储到Cache里了啊,怎么还是可以改的.

刚才写了句代码,还是这种情况:

           StringBuilder sb = new StringBuilder();
            sb.Append(
"hello");
            Response.Write(sb.ToString());


            Response.Write(
"<br/>");
            Cache.Insert(
"aa", sb);

            Response.Write(Cache.Get(
"aa").ToString());
            Response.Write(
"<br/>");

            sb.Append(
"aa");

            Response.Write(Cache.Get(
"aa").ToString());
            Response.Write(
"<br/>");
            
//输出helloaa

难道Cache存储的只是对象的引用类型,以前还真的没有注意到这个问题,对其它的类型是不是也会这样呢,又写了一个简单的程序了一下,果然如此:

            People p = new People();
            p.name 
= "aa";
            Cache.Insert(
"p", p);
            p.name 
= "bb";
            Response.Write(((People)Cache.Get(
"p")).name);
            
//输出bb

但是以前用于存储的HashTable也是引用类型啊,怎么没有注意过,写下测试代码:

原来真的如此,Cache只是在服务器端存储了对引用类型的引用吗?那么Session和ViewState呢

           People p = new People();
            p.name 
= "aa";
            Session[
"p"= p;
            p.name 
= "bb";
            Response.Write(((People)Session[
"p"]).name);
            
//输出bb

看来Session和Cache一样,只是适用的范围不一样,Session是为单独的一个用户存储.两个都存储在服务器上的内存上.
测试ViewState的时候,出了问题,提示要将对象People序列化,原来这样!!忘了都...

 [Serializable]
    
public class People
    
{
        
public string name; 
    }

  People p 
= new People();
            p.name 
= "aa";
            ViewState[
"p"= p;
            p.name 
= "bb";
            Response.Write(((People)ViewState[
"p"]).name);
            
//输出bb

原来竟然是这个样子,不过如果存储的是对象引用的话,那生命期呢,如果在这个生命期,而且在他存储的有效的范围内的修改都会影响到Cache里获取的结果吗?还是获取的也只是引用而已....明天研究..

 不过Cache理论上是应该存储一些不经常改变的经常使用的数据,这样经常改变,似乎有些有违规则了.

<think>首先,用户的问题是:“我想了解JavaCache的数据类型或实现方式请问JavaCache类型实现方式数据结构”。我需要基于提供的引用和之前的系统指令来回答。关键引用:-引用[1]:介绍EhCache配置,使用编程方式配置缓存管理器,涉及CacheManagerBuilder和CacheConfigurationBuilder。数据结构方面,提到了使用heap资源池。-引用[2]:介绍使用LinkedHashMap实现LRU缓存的方式。LinkedHashMap支持访问顺序,从而实现缓存淘汰策略(基于访问频率的淘汰)。-引用[3]:提到Memcached,一个高性能分布式内存对象缓存系统,存储对。-引用[4]:涉及GuavaCache的StatsCounter接口,用于记录缓存统计信息。系统指令:-所有行内数学表达式用`$...$`格式(但这里可能不涉及数学,所以可能需要忽略)。-独立公式用`$$...$$`单独成段(可能不适用)。-LaTeX语法正确(确保代码块正确)。-使用中文回答。-生成相关问题。-回答中引用的段落末尾自然地添加引用标识,例如:[^1]。用户的问题聚焦在JavaCache的类型、实现方式和数据结构上。我需要基于引用整合信息。梳理JavaCache的类型和实现方式:1.**类型**:-根据引用,有本地缓存(如EhCache,GuavaCache)和分布式缓存(如Memcached)。-EhCache:一个开源的Java缓存库。-LinkedHashMap:在Java集合中用于实现LRU缓存。-Memcached:分布式缓存系统。-GuavaCache:来自GoogleGuava库的缓存实现。2.**实现方式**:-**编程配置**:如引用[1]中的EhCache示例,使用构建器模式配置缓存。-**使用集合类**:如引用[2],使用LinkedHashMap来实现简单的LRU缓存。-**分布式实现**:如Memcached,提供API进行数据的读写。3.**数据结构**:-EhCache:使用堆内存资源池,如ResourcePoolsBuilder.heap(10),表示基于堆的缓存。-LinkedHashMap:基于哈希表和链表的数据结构,支持按照访问顺序排序。-Memcached:键存储。-GuavaCache:可能涉及记录统计信息的数据结构,如CacheStats。基于引用,我可以覆盖:-EhCache的配置和数据结构(基于引用[1])。-LinkedHashMap实现LRU(基于引用[2])。-Memcached作为分布式类型(基于引用[3])。-GuavaCache可能的相关部分(引用[4]提到StatsCounter)。回答结构:-清晰、逐步解释。-引入相关代码示例时,用代码块(如示例中的Python代码)。-最后生成相关问题。组织回答:1.**引言**:简要介绍JavaCache的常见类型。2.**详细实现方式**:-使用EhCache(编程配置)。-使用Java集合(LinkedHashMap)实现简单缓存。-分布式缓存(Memcached)。-其他如GuavaCache(可简要提及)。3.**数据结构**:解释每个实现背后的数据结构。4.**添加引用标识**:在每个相关部分末尾。5.**生成相关问题**:在最后部分。确保中文回答。最终回答大纲:-JavaCache类型:本地缓存(EhCache、GuavaCache)、分布式缓存(Memcached)。-实现方式示例:-EhCache:构建器配置,如引用[1]的代码。-LinkedHashMap:实现LRU,如引用[2]的代码。-Memcached:键API,如引用[3]。-数据结构:-EhCache:堆内存管理。-LinkedHashMap:哈希表加链表。-Memcached:分布式哈希表。-生成相关问题。相关问题示例:1.EhCache的具体配置选项有哪些?2.如何实现自定义的缓存淘汰策略?3.Java中有哪些开源的缓存库?</think> ### Java Cache 类型、实现方式与数据结构 Java 缓存(Cache)是一种用于存储临时数据以提高性能的机制,广泛用于减少数据库访问和计算开销。常见类型包括本地缓存(如 EhCache、Guava Cache)和分布式缓存(如 Memcached)。实现方式多样,涉及不同的配置方法和数据结构设计。以下我将基于核心概念逐步解释类型、实现方式和数据结构,确保内容清晰可靠。 #### 1. **Java Cache 的主要类型** Java 缓存根据作用范围可以分为两大类: - **本地缓存**:数据存储在应用进程的内存中,适合于单机环境。实现简单、性能高,但缓存数据不共享(如 EhCache、Guava Cache)[^1]。 - **分布式缓存**:数据存储在分布式内存集群中,支持多节点共享,适用于大规模应用(如 Memcached、Redis)[^3]。 这些类型的选择取决于应用需求:本地缓存适合高频读取、低并发场景;分布式缓存支持高可用和扩展性。 #### 2. **实现方式** Java 缓存的实现方式灵活多样,核心是通过编程或配置定义缓存行为和策略。以下基于引用示例,展示具体实现。 - **使用 EhCache 编程配置**:EhCache 是一个流行库,可通过构建器模式配置缓存管理器(CacheManager)和缓存实例。示例中,使用 CacheManagerBuilder 创建缓存池,并通过 ResourcePoolsBuilder 设置堆内存大小(如 heap(10) 表示容量限制)。数据结构基于 Java 对象存储对。 ```java CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder() .withCache("preConfigured", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10))) .build(); cacheManager.init(); Cache<Long, String> myCache = cacheManager.createCache("myCache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10))); myCache.put(1L, "da one!"); String value = myCache.get(1L); cacheManager.close(); ``` 这种方式实现了缓存的创建、读写和生命周期管理,适合静态配置场景[^1]。 - **使用 LinkedHashMap 实现 LRU 缓存**:基于 Java 集合类,通过 LinkedHashMap 实现最近最少使用(LRU)淘汰策略。accessOrder 参数设为 true 时,链表维护访问顺序,较早访问的条目会被优先淘汰。 ```java public class LRUCache { private final int CAPACITY; private LinkedHashMap<Integer, Integer> cache; public LRUCache(int capacity) { CAPACITY = capacity; cache = new LinkedHashMap<Integer, Integer>(capacity, 0.75f, true) { @Override protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) { return size() > CAPACITY; // 淘汰策略 } }; } public int get(int key) { return cache.getOrDefault(key, -1); } public void put(int key, int value) { cache.put(key, value); } } ``` 实现简单,无需外部依赖,适用于小型缓存需求[^2]。 - **分布式缓存如 Memcached**:通过分布式系统存储对数据,使用简单 API 进行读写。虽然原生非 Java 实现,但有 Java 客户端库支持。 ```java // 示例使用伪代码,Memcached Java 客户端(如 spymemcached) MemcachedClient client = new MemcachedClient(new InetSocketAddress("localhost", 11211)); client.set("key", 3600, "value"); // 设置键对,过期时间 3600 秒 String value = (String) client.get("key"); ``` 数据结构基于分布式哈希表,适合大规模数据共享和高并发访问[^3]。 - **Guava Cache 的实现**:Google Guava 库提供灵活的本地缓存,支持统计信息记录(如命中率、加载时间)。通过 CacheBuilder 配置,利用 StatsCounter 接口监控性能。 ```java Cache<String, Object> cache = CacheBuilder.newBuilder() .maximumSize(100) // 最大条目数 .recordStats() // 记录统计 .build(); ``` 数据通过哈希表存储,结合了内存管理和策略机制[^4]。 #### 3. **核心数据结构** Java 缓存的底层数据结构决定了其性能和适用性: - **本地缓存(如 EhCache 和 LinkedHashMap)**:使用 **哈希表(Hash Table)作为基础数据结构**,实现高效键查询(O(1) 平均访问时间)。EhCache 结合堆内存资源池(ResourcePools),数据存储在 JVM 堆中;LinkedHashMap 则添加双向链表维护访问顺序,用于淘汰策略[^1][^2]。这保证了快速读写,但需管理内存大小防止 OOM。 - **分布式缓存(如 Memcached)**:基于分布式哈希表(Distributed Hash Table, DHT),数据分片存储在多节点内存中。实现方式使用一致性哈希算法减少扩容影响,确保高可用性[^3]。 - **Guava Cache 等高级实现**:采用复合数据结构,如哈希表存储数据,链表或最小堆用于实现淘汰策略(如 LRU 或 LFU),并通过 StatsCounter 记录统计信息,便于优化[^4]。 #### 总结 Java Cache 的类型和实现取决于应用需求:本地缓存(如 EhCache 和 LinkedHashMap)结构简单、性能高;分布式缓存(如 Memcached)支持扩展。数据结构以哈希表为核心,通过链表或堆增强淘汰策略。选择时考虑数据量、并发量和淘汰规则(如 LRU)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值