缓存是服务器程序中经常用到的技术,使用缓存可以大大降低服务器的压力。目前常见的缓存工具都很好地解决了生命周期、存储、命中率等关键算法,但是绝大多数的缓存框架对于数据更新都是阻塞式的,即当缓存过期时会等待应用程序重新获取值。其性能曲线类似下图(假设刷新一次需要5ms):
阻塞式的缓存处理方式,每次的重新取值都会出现一次波峰,用户在使用系统的过程中将产生顿挫感。
NCache 建立了一套抽象的非阻塞式缓存模型与 API,应用 NCache 的缓存处理时效如下图所示:
使用 NCache 仅需在首次加载数据时停顿,此后的更新都将在后台线程完成。
NCache特性一览:
仅首次加载时阻塞,此后刷新都由后台完成
开发者可自定义线程池,控制线程调度及溢出机制
默认提供基于 FIFO 的内存存储,对象超出将被移除
支持链式数据存储,开发者可附加其他存储方式,如 Redis、Memcached、Ehcache
快速上手:
NCache 使用非常简单,只需将 jar 包放入classpath,然后即可调用。下面是一个简单的示例:
int cacheTTL=5*1000;//缓存有效期5秒钟 NCache<String> ncache=NCache.newInstance();//ncache可复用 ncache.setTimeToLive(cacheTTL); DataLoader<String> loader=new DataLoader<String>() {//loader可复用 @Override public String load() throws Exception { int expense=new Random().nextInt(2000);//随机模拟取数据性能消耗 String value="VALUE_"+expense; System.err.println("Reloading:"+value); Thread.sleep(expense); return value; } }; for(int i=0;i<10000;i++){ String value=ncache.get("somekey", loader); System.out.println("Get:"+value); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } }
源码:https://svn.zim-soft.com/svn/strato/tags/ncache/strato.ncache.v2_6_5 (用户名:guest 密码:无)
9.7. 示例: 并发的非阻塞缓存 本节中我们会做一个无阻塞的缓存,这种工具可以帮助我们来解决现实世界中并发程序出现但没有现成的库可以解决的问题。这个问题叫作缓存(memoizing)函数(译注:Memoization的定义: memoization 一词是Donald Michie 根据拉丁语memorandum杜撰的一个词。相应的动词、过去分词、ing形式有memoiz、memoized、me
非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 ServletInputStream.setReadListener 或ServletOutputStream.setWriteListener 方法时将抛出IllegalStateException。为了支持在 Ser
Web 容器中的非阻塞请求处理有助于提高对改善 Web 容器可扩展性不断增加的需求,增加 Web 容器可同时处理请求的连接数量。servlet 容器的非阻塞 IO 允许开发人员在数据可用时读取数据或在数据可写时写数据。非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 S
问题内容: 我读过某个地方,Java可以在大约12条机器指令中为对象分配内存。这对我来说非常令人印象深刻。据我了解,JVM使用的技巧之一是按块预分配内存。我认为,这有助于最大程度地减少对操作系统的请求数量,这是非常昂贵的。但是,即使是CAS操作,在现代处理器上也可能要花费多达150个周期。 那么,谁能在Java中解释内存分配的实际成本以及JVM使用哪些技巧来加快分配速度? 问题答案: JVM为每个
问题内容: 我在获取ncurses的getch()阻止时遇到了一些问题。默认操作似乎是非阻塞的(或者我错过了一些初始化)?我希望它可以像Windows中的getch()一样工作。我尝试了各种版本的 (并非同时全部)。如果可能的话,我宁愿不(明确地)使用any 。一个围绕残培环路(),检查特定的返回值是OK了。 问题答案: curses库是一揽子交易。如果不正确初始化库,您不能仅仅提出一个例程并希望
问题内容: 有没有一种方法可以以非阻塞方式使用python的socket.accept()来简单地运行它,并让我检查它是否有任何新连接?我 真的 不想使用线程。谢谢。 问题答案: 您可能想要类似的东西(请参阅文档)。您提供了三个套接字列表:您要监视其可读性,可写性和错误状态的套接字。当新的客户端正在等待时,服务器套接字将是可读的。 该功能将一直阻塞,直到套接字状态之一改变为止。如果您不想永远阻塞,
Go提供的网络接口,在用户层是阻塞的,这样最符合人们的编程习惯。在runtime层面,是用epoll/kqueue实现的非阻塞io,为性能提供了保障。 如何实现 底层非阻塞io是如何实现的呢?简单地说,所有文件描述符都被设置成非阻塞的,某个goroutine进行io操作,读或者写文件描述符,如果此刻io还没准备好,则这个goroutine会被放到系统的等待队列中,这个goroutine失去了运行权
问题内容: 我有这段代码可以在Linux中从Serial读取,但是我不知道在读取SerialPort时阻塞和非阻塞之间有什么区别,在哪种情况下哪个更好? 问题答案: 您提到的代码是IMO编码和注释不当的代码。该代码不符合POSIX的可移植性惯例,如正确设置终端模式和POSIX操作系统的串行编程指南中所述。该代码没有提到它使用非规范(也称为原始)模式,并且重用了“阻塞”和“非阻塞”术语来描述 VMI