精华内容
下载资源
问答
  • Guava缓存

    2020-01-09 17:54:43
    Guava Cache是一个全内存的本地缓存实现,它提供了线程安全的实现机制。整体上来说Guava cache 是本地缓存的不二之选,简单易用,性能好。 Guava适用性 你愿意消耗一些内存空间来提升速度。 你预料到某些键会被查询...

    Guava 是什么

    Guava Cache是一个全内存的本地缓存实现,它提供了线程安全的实现机制。整体上来说Guava cache 是本地缓存的不二之选,简单易用,性能好。

    Guava适用性

    你愿意消耗一些内存空间来提升速度。
    你预料到某些键会被查询一次以上。
    缓存中存放的数据总量不会超出内存容量。(Guava Cache 是单个应用运行时的本地缓存。它不把数据存放到文件或外部服务器。如果这不符合你的需求,请尝试 Memcached,redis 这类工具)

    Guava创建方法

    有两种方式
    1CacheLoader
    2Callable
    这里我只记录我用的方法Callable

        Cache<String, String> localCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(5, TimeUnit.MINUTES).build();
        //使用与redis一样localCache.put("key","value"),localCache.get("key")
    
    

    基于容量的回收:maximumSize:
    定时回收:expireAfterAccess

    Guava Cache的不足之处

    1是单个应用运行时的本地缓存,数据没有持久化存放到文件或外部服务器
    2单机缓存,受机器内存限制,重启应用缓存数据会丢失,应用分布式部署会出现缓存数据不一致的情况
    3分布式部署时如何保持缓存的一致性?

    原文参考:
    https://www.jianshu.com/p/b3c10fcdbf0f

    展开全文
  • guava缓存

    2017-02-27 11:28:58
    guava

    范例

    01 LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
    02         .maximumSize(1000)
    03         .expireAfterWrite(10, TimeUnit.MINUTES)
    04         .removalListener(MY_LISTENER)
    05         .build(
    06             new CacheLoader<Key, Graph>() {
    07                 public Graph load(Key key) throws AnyException {
    08                     return createExpensiveGraph(key);
    09                 }
    10         });

    适用性  

    缓存在很多场景下都是相当有用的。例如,计算或检索一个值的代价很高,并且对同样的输入需要不止一次获取值的时候,就应当考虑使用缓存。

    Guava Cache与ConcurrentMap很相似,但也不完全一样。最基本的区别是ConcurrentMap会一直保存所有添加的元素,直到显式地移除。相对地,Guava Cache为了限制内存占用,通常都设定为自动回收元素。在某些场景下,尽管LoadingCache 不回收元素,它也是很有用的,因为它会自动加载缓存。

    加载

    在使用缓存前,首先问自己一个问题:有没有合理的默认方法来加载或计算与键关联的值?如果有的话,你应当使用CacheLoader。如果没有,或者你想要覆盖默认的加载运算,同时保留"获取缓存-如果没有-则计算"[get-if-absent-compute]的原子语义,你应该在调用get时传入一个Callable实例。缓存元素也可以通过Cache.put方法直接插入,但自动加载是首选的,因为它可以更容易地推断所有缓存内容的一致性。

    CacheLoader

    LoadingCache是附带CacheLoader构建而成的缓存实现。创建自己的CacheLoader通常只需要简单地实现V load(K key) throws Exception方法。例如,你可以用下面的代码构建LoadingCache:

    01 LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
    02         .maximumSize(1000)
    03         .build(
    04             new CacheLoader<Key, Graph>() {
    05                 public Graph load(Key key) throws AnyException {
    06                     return createExpensiveGraph(key);
    07                 }
    08             });
    09  
    10 ...
    11 try {
    12     return graphs.get(key);
    13 catch (ExecutionException e) {
    14     throw new OtherException(e.getCause());
    15 }

    从LoadingCache查询的正规方式是使用get(K)方法。这个方法要么返回已经缓存的值,要么使用CacheLoader向缓存原子地加载新值。由于CacheLoader可能抛出异常,LoadingCache.get(K)也声明为抛出ExecutionException异常。如果你定义的CacheLoader没有声明任何检查型异常,则可以通过getUnchecked(K)查找缓存;但必须注意,一旦CacheLoader声明了检查型异常,就不可以调用getUnchecked(K)。

    01 LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
    02         .expireAfterAccess(10, TimeUnit.MINUTES)
    03         .build(
    04             new CacheLoader<Key, Graph>() {
    05                 public Graph load(Key key) { // no checked exception
    06                     return createExpensiveGraph(key);
    07                 }
    08             });
    09  
    10 ...
    11 return graphs.getUnchecked(key);

    getAll(Iterable<? extends K>)方法用来执行批量查询。默认情况下,对每个不在缓存中的键,getAll方法会单独调用CacheLoader.load来加载缓存项。如果批量的加载比多个单独加载更高效,你可以重载CacheLoader.loadAll来利用这一点。getAll(Iterable)的性能也会相应提升。

    注:CacheLoader.loadAll的实现可以为没有明确请求的键加载缓存值。例如,为某组中的任意键计算值时,能够获取该组中的所有键值,loadAll方法就可以实现为在同一时间获取该组的其他键值校注:getAll(Iterable<? extends K>)方法会调用loadAll,但会筛选结果,只会返回请求的键值对。

    Callable

    所有类型的Guava Cache,不管有没有自动加载功能,都支持get(K, Callable<V>)方法。这个方法返回缓存中相应的值,或者用给定的Callable运算并把结果加入到缓存中。在整个加载方法完成前,缓存项相关的可观察状态都不会更改。这个方法简便地实现了模式"如果有缓存则返回;否则运算、缓存、然后返回"。

    01 Cache<Key, Graph> cache = CacheBuilder.newBuilder()
    02         .maximumSize(1000)
    03         .build(); // look Ma, no CacheLoader
    04 ...
    05 try {
    06     // If the key wasn't in the "easy to compute" group, we need to
    07     // do things the hard way.
    08     cache.get(key, new Callable<Key, Graph>() {
    09         @Override
    10         public Value call() throws AnyException {
    11             return doThingsTheHardWay(key);
    12         }
    13     });
    14 catch (ExecutionException e) {
    15     throw new OtherException(e.getCause());
    16 }

    显式插入

    使用cache.put(key, value)方法可以直接向缓存中插入值,这会直接覆盖掉给定键之前映射的值。使用Cache.asMap()视图提供的任何方法也能修改缓存。但请注意,asMap视图的任何方法都不能保证缓存项被原子地加载到缓存中。进一步说,asMap视图的原子运算在Guava Cache的原子加载范畴之外,所以相比于Cache.asMap().putIfAbsent(K,
    V),Cache.get(K, Callable<V>) 应该总是优先使用。

    缓存回收

    一个残酷的现实是,我们几乎一定没有足够的内存缓存所有数据。你你必须决定:什么时候某个缓存项就不值得保留了?Guava Cache提供了三种基本的缓存回收方式:基于容量回收、定时回收和基于引用回收。

    基于容量的回收(size-based eviction)

    如果要规定缓存项的数目不超过固定值,只需使用CacheBuilder.maximumSize(long)。缓存将尝试回收最近没有使用或总体上很少使用的缓存项。——警告:在缓存项的数目达到限定值之前,缓存就可能进行回收操作——通常来说,这种情况发生在缓存项的数目逼近限定值时。

    另外,不同的缓存项有不同的“权重”(weights)——例如,如果你的缓存值,占据完全不同的内存空间,你可以使用CacheBuilder.weigher(Weigher)指定一个权重函数,并且用CacheBuilder.maximumWeight(long)指定最大总重。在权重限定场景中,除了要注意回收也是在重量逼近限定值时就进行了,还要知道重量是在缓存创建时计算的,因此要考虑重量计算的复杂度。

    01 LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
    02         .maximumWeight(100000)
    03         .weigher(new Weigher<Key, Graph>() {
    04             public int weigh(Key k, Graph g) {
    05                 return g.vertices().size();
    06             }
    07         })
    08         .build(
    09             new CacheLoader<Key, Graph>() {
    10                 public Graph load(Key key) { // no checked exception
    11                     return createExpensiveGraph(key);
    12                 }
    13             });

    定时回收(Timed Eviction)

    CacheBuilder提供两种定时回收的方法:

    • expireAfterAccess(long, TimeUnit):缓存项在给定时间内没有被读/写访问,则回收。请注意这种缓存的回收顺序和基于大小回收一样。
    • expireAfterWrite(long, TimeUnit):缓存项在给定时间内没有被写访问(创建或覆盖),则回收。如果认为缓存数据总是在固定时候后变得陈旧不可用,这种回收方式是可取的。

    如下文所讨论,定时回收周期性地在写操作中执行,偶尔在读操作中执行。

    测试定时回收

    对定时回收进行测试时,不一定非得花费两秒钟去测试两秒的过期。你可以使用Ticker接口和CacheBuilder.ticker(Ticker)方法在缓存中自定义一个时间源,而不是非得用系统时钟。

    基于引用的回收(Reference-based Eviction)

    通过使用弱引用的键、或弱引用的值、或软引用的值,Guava Cache可以把缓存设置为允许垃圾回收:

    • CacheBuilder.weakKeys():使用弱引用存储键。当键没有其它(强或软)引用时,缓存项可以被垃圾回收。因为垃圾回收仅依赖恒等式(==),使用弱引用键的缓存用==而不是equals比较键。
    • CacheBuilder.weakValues():使用弱引用存储值。当值没有其它(强或软)引用时,缓存项可以被垃圾回收。因为垃圾回收仅依赖恒等式(==),使用弱引用值的缓存用==而不是equals比较值。
    • CacheBuilder.softValues():使用软引用存储值。软引用只有在响应内存需要时,才按照全局最近最少使用的顺序回收。考虑到使用软引用的性能影响,我们通常建议使用更有性能预测性的缓存大小限定(见上文,基于容量回收)。使用软引用值的缓存同样用==而不是equals比较值。

    显式清除

    任何时候,你都可以显式地清除缓存项,而不是等到它被回收:


    展开全文
  • guava缓存数据到本地 缓存使您可以轻松地显着加速应用程序。 Java平台的两种出色的缓存实现是Guava缓存和Ehcache 。 尽管Ehcache功能丰富得多(例如其Searchable API ,将缓存持久化到磁盘或溢出到大内存的可能性)...

    guava缓存数据到本地

    缓存使您可以轻松地显着加速应用程序。 Java平台的两种出色的缓存实现是Guava缓存Ehcache 尽管Ehcache功能丰富得多(例如其Searchable API ,将缓存持久化到磁盘或溢出到大内存的可能性),但与Guava相比,它也带来了相当大的开销。 在最近的项目中,我发现需要将全面的缓存溢出到磁盘上,但与此同时,我经常需要使该缓存的特定值无效。 由于Ehcache的Searchable API仅可用于内存中的缓存,因此这使我陷入了两难境地。 但是,扩展Guava缓存以允许以结构化方式溢出到磁盘非常容易。 这使我既溢出到磁盘又需要必需的失效功能。 在本文中,我想展示如何实现这一目标。

    我将以实际Guava Cache实例的包装器形式实现此文件持久性缓存FilePersistingCache 当然,这不是最优雅的解决方案(更优雅的做法是使用这种行为来实现实际的Guava Cache ),但是在大多数情况下,我都会这样做。

    首先,我将定义一个受保护的方法,该方法创建前面提到的后备缓存:

    private LoadingCache<K, V> makeCache() {
      return customCacheBuild()
        .removalListener(new PersistingRemovalListener())
        .build(new PersistedStateCacheLoader());
    }
     
    protected CacheBuilder<K, V> customCacheBuild(CacheBuilder<K, V> cacheBuilder) {
      return CacheBuilder.newBuilder();
    }

    第一种方法将在内部使用以构建必要的缓存。 为了实现对缓存的任何自定义要求(例如,过期策略),应该重写第二种方法。 例如,这可以是条目或软引用的最大值。 此缓存将与其他任何Guava缓存一样使用。 缓存功能的关键是用于此缓存的RemovalListenerCacheLoader 我们将这两个实现定义为FilePersistingCache内部类:

    private class PersistingRemovalListener implements RemovalListener<K, V> {
      @Override
      public void onRemoval(RemovalNotification<K, V> notification) {
        if (notification.getCause() != RemovalCause.COLLECTED) {
          try {
            persistValue(notification.getKey(), notification.getValue());
          } catch (IOException e) {
            LOGGER.error(String.format("Could not persist key-value: %s, %s",
              notification.getKey(), notification.getValue()), e);
          }
        }
      }
    }
     
    public class PersistedStateCacheLoader extends CacheLoader<K, V> {
      @Override
      public V load(K key) {
        V value = null;
        try {
          value = findValueOnDisk(key);
        } catch (Exception e) {
          LOGGER.error(String.format("Error on finding disk value to key: %s",
            key), e);
        }
        if (value != null) {
          return value;
        } else {
          return makeValue(key);
        }
      }
    }

    从代码中可以明显FilePersistingCache ,这些内部类调用了我们尚未定义的FilePersistingCache方法。 这使我们可以通过重写此类来定义自定义序列化行为。 删除侦听器将检查清除缓存条目的原因。 如果RemovalCauseCOLLECTED ,缓存条目没有由用户手动删除,但它已被删除作为高速缓存的驱逐策略的结果。 因此,如果用户不希望删除条目,我们将仅尝试保留一个缓存条目。 CacheLoader将首先尝试从磁盘还原现有值并仅在无法还原该值时创建一个新值。

    缺少的方法定义如下:

    private V findValueOnDisk(K key) throws IOException {
      if (!isPersist(key)) return null;
      File persistenceFile = makePathToFile(persistenceDirectory, directoryFor(key));
      (!persistenceFile.exists()) return null;
      FileInputStream fileInputStream = new FileInputStream(persistenceFile);
      try {
        FileLock fileLock = fileInputStream.getChannel().lock();
        try {
          return readPersisted(key, fileInputStream);
        } finally {
          fileLock.release();
        }
      } finally {
        fileInputStream.close();
      }
    }
     
    private void persistValue(K key, V value) throws IOException {
      if (!isPersist(key)) return;
      File persistenceFile = makePathToFile(persistenceDirectory, directoryFor(key));
      persistenceFile.createNewFile();
      FileOutputStream fileOutputStream = new FileOutputStream(persistenceFile);
      try {
        FileLock fileLock = fileOutputStream.getChannel().lock();
        try {
          persist(key, value, fileOutputStream);
        } finally {
          fileLock.release();
        }
      } finally {
        fileOutputStream.close();
      }
    }
     
     
    private File makePathToFile(@Nonnull File rootDir, List<String> pathSegments) {
      File persistenceFile = rootDir;
      for (String pathSegment : pathSegments) {
        persistenceFile = new File(persistenceFile, pathSegment);
      }
      if (rootDir.equals(persistenceFile) || persistenceFile.isDirectory()) {
        throw new IllegalArgumentException();
      }
      return persistenceFile;
    }
     
    protected abstract List<String> directoryFor(K key);
     
    protected abstract void persist(K key, V value, OutputStream outputStream)
      throws IOException;
     
    protected abstract V readPersisted(K key, InputStream inputStream)
      throws IOException;
     
    protected abstract boolean isPersist(K key);

    所实现的方法在同步文件访问并保证流被适当关闭的同时,还要注意对值进行序列化和反序列化。 最后四种方法仍然是抽象的,并由缓存的用户来实现。 directoryFor(K)方法应为每个密钥标识一个唯一的文件名。 在最简单的情况下,密钥的K类的toString方法是以这种方式实现的。 此外,我还对persistreadPersistedisPersist方法进行了抽象化处理,以实现自定义序列化策略,例如使用Kryo 在最简单的情况下,您将使用内置的Java功能,该功能使用ObjectInputStreamObjectOutputStream 对于isPersist ,假设仅在需要序列化时才使用此实现,则将返回true 我添加了此功能以支持混合缓存,在混合缓存中,您只能将值序列化为某些键。 确保不要在persistreadPersisted方法中关闭流,因为文件系统锁依赖于要打开的流。 上面的实现将为您关闭流。

    最后,我添加了一些服务方法来访问缓存。 当然,实现Guava的Cache接口将是一个更优雅的解决方案:

    public V get(K key) {
      return underlyingCache.getUnchecked(key);
    }
     
    public void put(K key, V value) {
      underlyingCache.put(key, value);
    }
     
    public void remove(K key) {
      underlyingCache.invalidate(key);
    }
     
    protected Cache<K, V> getUnderlyingCache() {
      return underlyingCache;
    }

    当然,可以进一步改善该解决方案。 如果在并发场景中使用缓存,请注意, RemovalListener是除大多数Guava缓存方法以外的异步执行的。 从代码中可以明显看出,我添加了文件锁,以避免在文件系统上发生读/写冲突。 但是,这种异步性确实意味着即使内存中仍然有一个值,也很少有机会重新创建值条目。 如果需要避免这种情况,请确保在包装器的get方法中调用基础缓存的cleanUp方法。 最后,记住在缓存过期时清理文件系统。 最佳地,您将使用系统的临时文件夹存储高速缓存条目,从而完全避免此问题。 在示例代码中,目录由名为persistenceDirectory的实例字段表示,该实例字段可以例如在构造函数中初始化。

    更新 :我对上面描述的内容进行了干净的实现,您可以在Git Hub页面Maven Central找到这些实现。 如果需要将缓存对象存储在磁盘上,请随时使用它。

    参考: My Java博客JCG合作伙伴 Rafael Winterhalter 扩展了Guava缓存以溢出到磁盘

    翻译自: https://www.javacodegeeks.com/2013/12/extending-guava-caches-to-overflow-to-disk.html

    guava缓存数据到本地

    展开全文
  • Guava缓存详解及使用

    千次阅读 2020-07-05 15:17:47
    本文主要介绍下Guava缓存的配置详解及相关使用 缓存分为本地缓存与分布式缓存。本地缓存为了保证线程安全问题,一般使用`ConcurrentMap`的方式保存在内存之中,而常见的分布式缓存则有`Redis`,`MongoDB`等。

    缓存

    缓存分为本地缓存与分布式缓存。本地缓存为了保证线程安全问题,一般使用ConcurrentMap的方式保存在内存之中,而常见的分布式缓存则有RedisMongoDB等。

    • 一致性:本地缓存由于数据存储于内存之中,每个实例都有自己的副本,可能会存在不一致的情况;分布式缓存则可有效避免这种情况
    • 开销:本地缓存会占用JVM内存,会影响GC及系统性能;分布式缓存的开销则在于网络时延和对象序列化,故主要影响调用时延
    • 适用场景:本地缓存适用于数据量较小或变动较少的数据;分布式缓存则适用于一致性要求较高及数量量大的场景(可弹性扩容)

    本地缓存适用于数据量较小或变动较少的数据,因为变动多需要考虑到不同实例的缓存一致性问题,而数据量大则需要考虑缓存回收策略及GC相关的问题

    Guava cache

    Guava Cache 是Google Fuava中的一个内存缓存模块,用于将数据缓存到JVM内存中。

    • 提供了get、put封装操作,能够集成数据源 ;
    • 线程安全的缓存,与ConcurrentMap相似,但前者增加了更多的元素失效策略,后者只能显示的移除元素;
    • Guava Cache提供了多种基本的缓存回收方式
    • 监控缓存加载/命中情况

    通常,Guava缓存适用于以下情况:

    • 愿意花费一些内存来提高速度。
    • 使用场景有时会多次查询key。
    • 缓存将不需要存储超出RAM容量的数据

    详细配置

    缓存的并发级别

    Guava提供了设置并发级别的API,使得缓存支持并发的写入和读取。与ConcurrentHashMap类似,Guava cache的并发也是通过分离锁实现。在通常情况下,推荐将并发级别设置为服务器cpu核心数。

    CacheBuilder.newBuilder()
    		// 设置并发级别为cpu核心数,默认为4
    		.concurrencyLevel(Runtime.getRuntime().availableProcessors()) 
    		.build();
    

    缓存的初始容量设置

    我们在构建缓存时可以为缓存设置一个合理大小初始容量,由于Guava的缓存使用了分离锁的机制,扩容的代价非常昂贵。所以合理的初始容量能够减少缓存容器的扩容次数。

    CacheBuilder.newBuilder()
    		// 设置初始容量为100
    		.initialCapacity(100)
    		.build();
    

    设置最大存储

    Guava Cache可以在构建缓存对象时指定缓存所能够存储的最大记录数量。当Cache中的记录数量达到最大值后再调用put方法向其中添加对象,Guava会先从当前缓存的对象记录中选择一条删除掉,腾出空间后再将新的对象存储到Cache中。

    CacheBuilder.newBuilder()
    		// 设置最大容量为1000
    		.maximumSize(1000)
    		.build();
    

    缓存清除策略

    1. 基于存活时间的清除策略
    • expireAfterWrite 写缓存后多久过期
    • expireAfterAccess 读写缓存后多久过期
      存活时间策略可以单独设置或组合配置
    1. 基于容量的清除策略
      通过CacheBuilder.maximumSize(long)方法可以设置Cache的最大容量数,当缓存数量达到或接近该最大值时,Cache将清除掉那些最近最少使用的缓存

    2. 基于权重的清除 策略
      使用CacheBuilder.weigher(Weigher)指定一个权重函数,并且用CacheBuilder.maximumWeight(long)指定最大总重。

    如每一项缓存所占据的内存空间大小都不一样,可以看作它们有不同的“权重”(weights),作为执行清除策略时优化回收的对象

    LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
           .maximumWeight(100000)
           .weigher(new Weigher<Key, Graph>() {
              public int weigh(Key k, Graph g) {
                return g.vertices().size();
              }
            })
           .build(
               new CacheLoader<Key, Graph>() {
                 public Graph load(Key key) { // no checked exception
                   return createExpensiveGraph(key);
                 }
               });
    
    1. 显式清除
    • 清除单个key:Cache.invalidate(key)
    • 批量清除key:Cache.invalidateAll(keys)
    • 清除所有缓存项:Cache.invalidateAll()
    1. 基于引用的清除策略
      在构建Cache实例过程中,通过设置使用弱引用的键、或弱引用的值、或软引用的值,从而使JVM在GC时顺带实现缓存的清除
    • CacheBuilder.weakKeys():使用弱引用存储键。当键没有其它(强或软)引用时,缓存项可以被垃圾回收
    • CacheBuilder.weakValues():使用弱引用存储值。当值没有其它(强或软)引用时,缓存项可以被垃圾回收
    • CacheBuilder.softValues():使用软引用存储值。软引用只有在响应内存需要时,才按照全局最近最少使用的顺序回收。考虑到使用软引用的性能影响,我们通常建议使用更有性能预测性的缓存大小限定

    垃圾回收仅依赖==恒等式,使用弱引用键的缓存用而不是equals(),即同一对象引用。

    Cache

    显式put操作置入内存

    private static Cache<Integer, Integer> numCache = CacheBuilder.newBuilder()
            .expireAfterWrite(5, TimeUnit.MINUTES)
            .build();
    
    public static void main(String[] args) throws Exception {
        System.out.println(numCache.getIfPresent(1));
        Thread.sleep(1000);
        System.out.println(numCache.getIfPresent(1));
        Thread.sleep(1000);
        numCache.put(1, 5);
        System.out.println(numCache.getIfPresent(1));
        // console: null null 5
    }
    

    LoadingCache

    使用自定义ClassLoader加载数据,置入内存中。从LoadingCache中获取数据时,若数据存在则直接返回;若数据不存在,则根据ClassLoaderload方法加载数据至内存,然后返回该数据

    private static LoadingCache<Integer,Integer> numCache = CacheBuilder.newBuilder().
            expireAfterWrite(5L, TimeUnit.MINUTES).
            maximumSize(5000L).
            build(new CacheLoader<Integer, Integer>() {
                @Override
                public Integer load(Integer key) throws Exception {
                    System.out.println("no cache");
                    return key * 5;
                }
            });
    
    public static void main(String[] args) throws Exception {
        System.out.println(numCache.get(1));
        Thread.sleep(1000);
        System.out.println(numCache.get(1));
        Thread.sleep(1000);
        numCache.put(1, 6);
        System.out.println(numCache.get(1));
        // console: 5 5 6
    }
    

    参考资料:

    1. Google CachesExplained
    展开全文
  • Guava 缓存教程

    千次阅读 2018-04-11 22:12:17
    Guava 缓存 本文我们看下Guava Cache的实现,包括基本使用,驱逐策略,刷新缓存以及一些有趣的批处理操作。最后,我们再看看缓存发出的删除通知功能。 如何使用Guava Cache 先来看一个简单示例,缓存字符串实例...
  • google guava缓存分析

    2018-09-06 16:50:11
    guava缓存过期时间分为两种,一种是从写入时开始计时,一种是从最后访问时间开始计时,而且guava缓存的过期时间是设置到整个一组缓存上的;这和EHCache,redis,memcached等不同,这些缓存系统设置都将缓存时间设置...
  • Guava-Cache-Demo 演示如何使用 Guava 缓存。 此示例应用程序使用 Google Books API 获取给定 ISBN 的图书的详细信息。
  • guava 缓存失效

    2019-08-05 16:55:06
    设置guava 缓存失效时间和缓存移除 import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import java.util.concurrent.TimeUnit; /** * @Description: * @Param: * @return...
  • Guava缓存的过期

    2021-03-24 15:33:43
    Guava缓存是谷歌的一种本地缓存,缓存是通过使用本机的内存来存储的,实现原理类似于ConcurrentHashMap, Guava适用于以下的场景: 1.消耗内存空间来提升速度 2.你预料到某些键会被查询一次以上 3.缓存中存放的...
  • Guava缓存项目实战

    千次阅读 2018-08-16 21:21:21
    项目中涉及到数据缓存,对一致性要求还行,本来打算用Guava做。后来发现6台机器且数据量3亿左右,内存大小... * 〈功能详细描述〉Guava缓存处理抽象类 * * @author wangzha * @see [相关类/方法](可选) * @si...
  • Guava缓存实战及使用场景 摘要:本文先介绍了Guava Cache囊括的基本使用方法,然后结合体系类图和LocalCache的数据结构对典型的几个方法源码进行流程分析。重点 缓存的命中率,缓存的失效时间,缓存的OOM,缓存的...
  • GUAVA缓存失效清理

    千次阅读 2019-06-26 09:33:50
    GUAVA缓存虽然有expireAfterWrite/expireAfterAccess方法和expire的监听器,但是guava自身并不会定时去判断缓存是否失效,触发判断失效逻辑是调用get方法。这自然很难满足需要对失效缓存进行监控的场景。解决方案...
  • 最近在工作中使用到了Google Guava缓存功能,感觉还是不错,这周末顺便把它深入一点的学习了一下。  我们为什么需缓存?主要原因是:当计算或获取一个值的时候代价很高,或者频繁获取一个值的时候,我们为了提高...
  • springboot集成Guava缓存

    2017-11-08 19:17:00
    很久没有写博客了,这段时间一直忙于看论文,写论文,简直头大,感觉还是做项目比较舒服,呵呵,闲话不多说,今天学习了下Guava缓存,这跟Redis类似的,但是适用的场景不一样,学习下吧。今天我们主要是springboot...
  • Java平台的两种出色的缓存实现是Guava缓存和Ehcache 。 尽管Ehcache功能丰富得多(例如其Searchable API ,将缓存持久化到磁盘或溢出到大内存的可能性),但与Guava相比,它也带来了相当大的开销。 在最近的项目中...
  • Guava缓存中如何查看已缓存数据的剩余时间 ![图片说明](https://img-ask.csdn.net/upload/202002/10/1581305342_170642.png)![图片说明](https://img-ask.csdn.net/upload/202002/10/1581305350_115412.png)
  • Guava 缓存 使用

    2015-05-28 17:34:12
    项目中最近遇到一个问题,查到最后发现,是guava缓存的问题。项目中设定的过期时间是2小时(是两小时没有访问的话,就会过期,如果两个小时内有访问就不会过期),还可以通过refresh操作来进行刷新缓存内容,项目中...
  • Guava缓存的使用

    2019-03-01 14:42:28
    guava缓存于本地内存中,速度要快于redis…… maven依赖: &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-...
  • Springboot使用Google guava缓存 开发环境 springboot guava docker-client 应用场景 用来存储DockerClient的client连接,项目通过操作docker-client提供对docker的可视化界面操作,操作范围没有固定,可以是...
  • 具体情况要根据个人电脑配置,采用Guava缓存之后qps提升近5倍~~~ 对首页轮播图列表接口采用Guava缓存的QPS:18000左右 对首页轮播图列表接口不采用Guava缓存的QPS:4000左右
  • spring boot使用guava缓存

    2018-08-11 15:48:00
    1.pom中插入依赖: <!--guava缓存cache--> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> &...
  • 介绍两种Google guava缓存使用方式

    千次阅读 2019-04-10 18:05:48
    介绍两种Google guava缓存使用方式 使用场景:计算或检索一个值的代价很高,并且对同样的输入需要不止一次获取值的时候,就应当考虑使用缓存。 方式一 import java.util.Random; import java.util.Scanner; ...
  • GUAVA缓存+递归查树

    千次阅读 2018-10-09 17:36:59
    //GUAVA缓存 private LoadingCache&lt;Long, List&lt;Long&gt;&gt; treeCacheBuilder = CacheBuilder.newBuilder() .expireAfterWrite(2, TimeUnit.MINUTES).build(new CacheLoader&lt;Long, ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,781
精华内容 7,112
关键字:

guava缓存