redis介紹、使用場景,請參考Redis總結(一)redis
redis配置、發佈訂閱,請參考Redis總結(二)數據庫
一、redis分佈式鎖的使用緩存
try{lock()}finally{unLock()}分佈式
/** * 獲取鎖 */ public static boolean lock(String key, int seconds) { try { Object value = jedisUtil.get(key); if (value != null) { log.info("【鎖】任務已被鎖定,KEY=" + key); return false; } if (jedisUtil.setnx(key, "", seconds) == 1) { log.info("【鎖】鎖定當前任務,KEY=" + key); return true; } } catch (Exception e) { log.error("【鎖】任務解鎖時出錯", e); } return false; } /** * 釋放鎖 */ public synchronized static void unLock(String key) { try { Object value = jedisUtil.get(key); if (value != null) { jedisUtil.del(key); } log.info("【鎖】解鎖當前任務,KEY=" + key); } catch (Exception e) { log.error("【鎖】任務解鎖時出錯", e); } }
基於內存的鎖ide
private static final AtomicBoolean handleAccessDataFlag = new AtomicBoolean(true);
使用volatile的時候要注意,volatile 變量具備 synchronized 的可見性特性,可是不具有原子特性,線程可以自動發現 volatile 變量的最新值。所以做爲內存鎖的時候,須要配合synchronized 塊使用。.net
使用volatile的條件是:線程
a、對變量的寫操做不依賴於當前值。blog
b、該變量沒有包含在具備其餘變量的不變式中隊列
private volatile boolean status;// 當前主機狀態,1:可用,0不可用
二、redis隊列的使用內存
public void handleUploadAccessData(String tableName,String userName,StringBuffer realPath) throws Exception{ Jedis jedis = null; try { jedis = jedisUtil.getJedis(); // 若是當前表正在執行則放入隊列 if(jedis.llen(tableName) != 0){ // 放入隊列等待 logger.info("臺帳轉換進入隊列等待………………,隊列名爲:" + tableName); jedis.lpush(tableName,userName); return; } // 執行放入隊列 jedis.lpush(tableName,userName); // 設置失效時間,防止出現異常消費不了的狀況 jedis.expire(tableName,60*30); // 循環執行隊列中的消息 while(true){ //todo to do you business jedis.lpop(tableName); if(jedis.llen(tableName) == 0){ return; } } } catch (Exception e) { jedis.lpop(tableName); }finally { if(jedis != null){ jedis.close(); } } }
三、redis緩存的使用
@Override public List<AccessDic> getCFAccessDic() { List<AccessDic> assetDics =null; try { assetDics = jedisUtil.getLs(JedisKey.getCFPrefixkey()); if(assetDics == null || assetDics.size() == 0){ // 查詢數據庫 // assetDics = dao.method(); jedisUtil.setLs(JedisKey.getCFPrefixkey(), assetDics, 1 * 60 * 60); } } catch (Exception e) { //todo } return assetDics; }