<pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

          <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

          <p id="bbfd9"></p>

          <p id="bbfd9"><cite id="bbfd9"></cite></p>

            <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

            <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
            <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
            java語言

            Java如何實現一個簡單的緩存

            時間:2025-04-13 20:10:32 java語言 我要投稿
            • 相關推薦

            Java如何實現一個簡單的緩存

              緩存是在web開發中經常用到的,將程序經常使用到或調用到的對象存在內存中,或者是耗時較長但又不具有實時性的查詢數據放入內存中,在一定程度上可以提高性能和效率。那么,用Java如何實現一個簡單的緩存?下面百分網小編帶大家一起來看看詳細內容,希望對大家有所幫助!想了解更多相關信息請持續關注我們應屆畢業生考試網!

              創建緩存對象EntityCache.java

              public class EntityCache {

              /**

              * 保存的數據

              */

              private Object datas;

              /**

              * 設置數據失效時間,為0表示永不失效

              */

              private long timeOut;

              /**

              * 最后刷新時間

              */

              private long lastRefeshTime;

              public EntityCache(Object datas, long timeOut, long lastRefeshTime) {

              this.datas = datas;

              this.timeOut = timeOut;

              this.lastRefeshTime = lastRefeshTime;

              }

              public Object getDatas() {

              return datas;

              }

              public void setDatas(Object datas) {

              this.datas = datas;

              }

              public long getTimeOut() {

              return timeOut;

              }

              public void setTimeOut(long timeOut) {

              this.timeOut = timeOut;

              }

              public long getLastRefeshTime() {

              return lastRefeshTime;

              }

              public void setLastRefeshTime(long lastRefeshTime) {

              this.lastRefeshTime = lastRefeshTime;

              }

              }

              定義緩存操作接口,ICacheManager.java

              public interface ICacheManager {

              /**

              * 存入緩存

              * @param key

              * @param cache

              */

              void putCache(String key, EntityCache cache);

              /**

              * 存入緩存

              * @param key

              * @param cache

              */

              void putCache(String key, Object datas, long timeOut);

              /**

              * 獲取對應緩存

              * @param key

              * @return

              */

              EntityCache getCacheByKey(String key);

              /**

              * 獲取對應緩存

              * @param key

              * @return

              */

              Object getCacheDataByKey(String key);

              /**

              * 獲取所有緩存

              * @param key

              * @return

              */

              Map<String, EntityCache> getCacheAll();

              /**

              * 判斷是否在緩存中

              * @param key

              * @return

              */

              boolean isContains(String key);

              /**

              * 清除所有緩存

              */

              void clearAll();

              /**

              * 清除對應緩存

              * @param key

              */

              void clearByKey(String key);

              /**

              * 緩存是否超時失效

              * @param key

              * @return

              */

              boolean isTimeOut(String key);

              /**

              * 獲取所有key

              * @return

              */

              Set<String> getAllKeys();

              }

              實現接口ICacheManager,CacheManagerImpl.java

              這里我使用了ConcurrentHashMap來保存緩存,本來以為這樣就是線程安全的,其實不然,在后面的測試中會發現它并不是線程安全的。

              public class CacheManagerImpl implements ICacheManager {

              private static Map<String, EntityCache> caches = new ConcurrentHashMap<String, EntityCache>();

              /**

              * 存入緩存

              * @param key

              * @param cache

              */

              public void putCache(String key, EntityCache cache) {

              caches.put(key, cache);

              }

              /**

              * 存入緩存

              * @param key

              * @param cache

              */

              public void putCache(String key, Object datas, long timeOut) {

              timeOut = timeOut > 0 ? timeOut : 0L;

              putCache(key, new EntityCache(datas, timeOut, System.currentTimeMillis()));

              }

              /**

              * 獲取對應緩存

              * @param key

              * @return

              */

              public EntityCache getCacheByKey(String key) {

              if (this.isContains(key)) {

              return caches.get(key);

              }

              return null;

              }

              /**

              * 獲取對應緩存

              * @param key

              * @return

              */

              public Object getCacheDataByKey(String key) {

              if (this.isContains(key)) {

              return caches.get(key).getDatas();

              }

              return null;

              }

              /**

              * 獲取所有緩存

              * @param key

              * @return

              */

              public Map<String, EntityCache> getCacheAll() {

              return caches;

              }

              /**

              * 判斷是否在緩存中

              * @param key

              * @return

              */

              public boolean isContains(String key) {

              return caches.containsKey(key);

              }

              /**

              * 清除所有緩存

              */

              public void clearAll() {

              caches.clear();

              }

              /**

              * 清除對應緩存

              * @param key

              */

              public void clearByKey(String key) {

              if (this.isContains(key)) {

              caches.remove(key);

              }

              }

              /**

              * 緩存是否超時失效

              * @param key

              * @return

              */

              public boolean isTimeOut(String key) {

              if (!caches.containsKey(key)) {

              return true;

              }

              EntityCache cache = caches.get(key);

              long timeOut = cache.getTimeOut();

              long lastRefreshTime = cache.getLastRefeshTime();

              if (timeOut == 0 || System.currentTimeMillis() - lastRefreshTime >= timeOut) {

              return true;

              }

              return false;

              }

              /**

              * 獲取所有key

              * @return

              */

              public Set<String> getAllKeys() {

              return caches.keySet();

              }

              }

              CacheListener.java,監聽失效數據并移除。

              public class CacheListener{

              Logger logger = Logger.getLogger("cacheLog");

              private CacheManagerImpl cacheManagerImpl;

              public CacheListener(CacheManagerImpl cacheManagerImpl) {

              this.cacheManagerImpl = cacheManagerImpl;

              }

              public void startListen() {

              new Thread(){

              public void run() {

              while (true) {

              for(String key : cacheManagerImpl.getAllKeys()) {

              if (cacheManagerImpl.isTimeOut(key)) {

              cacheManagerImpl.clearByKey(key);

              logger.info(key + "緩存被清除");

              }

              }

              }

              }

              }.start();

              }

              }

              測試類TestCache.java

              public class TestCache {

              Logger logger = Logger.getLogger("cacheLog");

              /**

              * 測試緩存和緩存失效

              */

              @Test

              public void testCacheManager() {

              CacheManagerImpl cacheManagerImpl = new CacheManagerImpl();

              cacheManagerImpl.putCache("test", "test", 10 * 1000L);

              cacheManagerImpl.putCache("myTest", "myTest", 15 * 1000L);

              CacheListener cacheListener = new CacheListener(cacheManagerImpl);

              cacheListener.startListen();

              logger.info("test:" + cacheManagerImpl.getCacheByKey("test").getDatas());

              logger.info("myTest:" + cacheManagerImpl.getCacheByKey("myTest").getDatas());

              try {

              TimeUnit.SECONDS.sleep(20);

              } catch (InterruptedException e) {

              e.printStackTrace();

              }

              logger.info("test:" + cacheManagerImpl.getCacheByKey("test"));

              logger.info("myTest:" + cacheManagerImpl.getCacheByKey("myTest"));

              }

              /**

              * 測試線程安全

              */

              @Test

              public void testThredSafe() {

              final String key = "thread";

              final CacheManagerImpl cacheManagerImpl = new CacheManagerImpl();

              ExecutorService exec = Executors.newCachedThreadPool();

              for (int i = 0; i < 100; i++) {

              exec.execute(new Runnable() {

              public void run() {

              if (!cacheManagerImpl.isContains(key)) {

              cacheManagerImpl.putCache(key, 1, 0);

              } else {

              //因為+1和賦值操作不是原子性的,所以把它用synchronize塊包起來

              synchronized (cacheManagerImpl) {

              int value = (Integer) cacheManagerImpl.getCacheDataByKey(key) + 1;

              cacheManagerImpl.putCache(key,value , 0);

              }

              }

              }

              });

              }

              exec.shutdown();

              try {

              exec.awaitTermination(1, TimeUnit.DAYS);

              } catch (InterruptedException e1) {

              e1.printStackTrace();

              }

              logger.info(cacheManagerImpl.getCacheDataByKey(key).toString());

              }

              }

              testCacheManager()輸出結果如下:

              2017-4-17 10:33:51 io.github.brightloong.cache.TestCache testCacheManager

              信息: test:test

              2017-4-17 10:33:51 io.github.brightloong.cache.TestCache testCacheManager

              信息: myTest:myTest

              2017-4-17 10:34:01 io.github.brightloong.cache.CacheListener$1 run

              信息: test緩存被清除

              2017-4-17 10:34:06 io.github.brightloong.cache.CacheListener$1 run

              信息: myTest緩存被清除

              2017-4-17 10:34:11 io.github.brightloong.cache.TestCache testCacheManager

              信息: test:null

              2017-4-17 10:34:11 io.github.brightloong.cache.TestCache testCacheManager

              信息: myTest:null

              testThredSafe()輸出結果如下(選出了各種結果中的一個舉例):

              2017-4-17 10:35:36 io.github.brightloong.cache.TestCache testThredSafe

              信息: 96

              可以看到并不是預期的結果100,為什么呢?ConcurrentHashMap只能保證單次操作的原子性,但是當復合使用的時候,沒辦法保證復合操作的原子性,以下代碼:

              if (!cacheManagerImpl.isContains(key)) {

              cacheManagerImpl.putCache(key, 1, 0);

              }

              多線程的時候回重復更新value,設置為1,所以出現結果不是預期的100。所以辦法就是在CacheManagerImpl.java中都加上synchronized,但是這樣一來相當于操作都是串行,使用ConcurrentHashMap也沒有什么意義,不過只是簡單的緩存還是可以的。或者對測試方法中的run里面加上synchronized塊也行,都是大同小異。更高效的方法我暫時也想不出來,希望大家能多多指教。

            【Java如何實現一個簡單的緩存】相關文章:

            Java 中常用緩存Cache機制的實現08-27

            java的緩存機制07-29

            java的緩存機制簡介09-06

            php頁面緩存實現方法07-20

            java如何實現漢諾塔08-08

            Java 隊列實現原理及簡單實現代碼09-13

            java通用組合算法如何實現09-12

            Java中如何實現顯示動態的時間09-28

            如何在java中實現左右鍵菜單10-30

                    <pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

                    <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

                    <p id="bbfd9"></p>

                    <p id="bbfd9"><cite id="bbfd9"></cite></p>

                      <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

                      <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
                      <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
                      飘沙影院