/** * 基於redis的分佈式鎖工具 * * @author yuyufeng * */ public class LockUtil { // 獲取redis static JedisPool jedisPool; static { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(100); config.setMaxIdle(5); config.setMaxWaitMillis(1000); config.setTestOnBorrow(false); // 構造池 jedisPool = new JedisPool(config, "127.0.0.1", 6379, 1000, "12345"); } // redis鍵值前綴標識 private final static String PREFIX = "LOCK-FLAG-"; // 默認獲取鎖的等待時間 private final static Integer WAITTIME = 200; /** * 獲取鎖 * * @param uid:鎖的惟一標識 * @param expire:鎖自動釋放時間 * @return true:得到鎖;false:鎖已被佔用 */ public static Boolean getLock(String uid, Integer expire) { if (expire < 0) { return false; } Long beginTime = System.currentTimeMillis(); do { Jedis jedis = jedisPool.getResource(); //防止程序出錯設置鍵值不失效 if(jedis.ttl(PREFIX + uid) == -1){ jedis.expire(PREFIX + uid, expire); } Long res = jedis.incr(PREFIX + uid); if (res == 1) { jedis.expire(PREFIX + uid, expire); if (jedis != null) { try { jedis.close(); } catch (Exception e1) { e1.printStackTrace(); } } return true; } if (jedis != null) { try { jedis.close(); } catch (Exception e1) { e1.printStackTrace(); } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.print("."); } while ((System.currentTimeMillis() - beginTime) < WAITTIME); return false; } /** * 獲取鎖 * * @param uid:鎖的惟一標識 * @param expire:鎖自動釋放時間 * @param timeout:超時等待時間 * @return true:得到鎖;false:鎖已被佔用 */ public static Boolean getLock(String uid, Integer expire, Integer timeout) { if (expire < 0) { return false; } Long beginTime = System.currentTimeMillis(); do { Jedis jedis = jedisPool.getResource(); //防止程序出錯設置鍵值不失效 if(jedis.ttl(PREFIX + uid) == -1){ jedis.expire(PREFIX + uid, expire); } Long res = jedis.incr(PREFIX + uid); if (res == 1) { jedis.expire(PREFIX + uid, expire); if (jedis != null) { try { jedis.close(); } catch (Exception e1) { e1.printStackTrace(); } } return true; } if (jedis != null) { try { jedis.close(); } catch (Exception e1) { e1.printStackTrace(); } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.print("."); } while ((System.currentTimeMillis() - beginTime) < timeout); return false; } /** * 手動釋放鎖 * * @param uid:鎖的惟一標識 */ public static void returnLock(String uid) { Jedis jedis = jedisPool.getResource(); jedis.del(PREFIX + uid); if (jedis != null) { try { jedis.close(); } catch (Exception e1) { e1.printStackTrace(); } } System.out.println("手動釋放鎖:" + uid); } }
/** * 測試 * * @param args */ public static void main(String[] args) { AtomicInteger ai = new AtomicInteger(1); AtomicInteger count = new AtomicInteger(0); for (int i = 0; i < 30; i++) { new Thread() { @Override public void run() { String uid = "a" + ai.incrementAndGet() % 10; // 獲取鎖,並設置10秒失效 Boolean lock = LockUtil.getLock(uid, 10); System.out.println(uid + "取鎖結果:" + lock); if (lock) { // dosomething.. count.incrementAndGet(); } System.out.println("當前獲取鎖的數量:"+count); } }.start(); } // 手動解鎖測試,超時測試 //Boolean lock = LockUtil.getLock("testReturnKey", 1); //System.out.println("testReturnKey" + "取鎖結果:" + lock); // LockUtil.returnLock("testReturnKey"); }