zoukankan      html  css  js  c++  java
  • redis的分布式锁工具LockUtil

    /**
     * 基于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");
     
    	}
    

      

  • 相关阅读:
    Linux客户/服务器程序设计范式——阿帕奇服务器(多进程)
    Linux客户/服务器程序设计范式2——并发服务器(进程池)
    封装readn
    C++学习之路: 函数适配器
    C++学习之路: 智能指针入门
    C++学习之路: 单例模板
    C++学习之路: 左值&右值 的讨论 和 ”move“ 值传递方式
    C++学习之路: 特殊操作符->的重载
    C++学习之路: 模板函数
    C++学习之路: 时间戳 封装成类
  • 原文地址:https://www.cnblogs.com/dinghaoran/p/11202454.html
Copyright © 2011-2022 走看看