标签:
普通方式
直接看代码
package com.whereta.jedis; import org.springframework.stereotype.Component; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import javax.annotation.Resource; import java.util.Calendar; import java.util.Date; import java.util.concurrent.TimeUnit; /** * Created by vincent on 15-10-14. */ @Component("jedisLock") public class JedisLock { public class CacheName { public static final String ADD_BEAN_AFTER_CHECK_LOCK_KEY = "ADDBeanAfterCheckLock"; } @Resource private JedisPool jedisPool; public void addBeanAfterCheck(int userId) { Jedis jedis = jedisPool.getResource(); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.MILLISECOND, 0); Date calendarTime = calendar.getTime(); long time = calendarTime.getTime(); //以用户id为key,不同用户调用同一个方法不会加锁 String key = CacheName.ADD_BEAN_AFTER_CHECK_LOCK_KEY + ":" + userId; try { if (jedis != null) { Long lock = jedis.setnx(key, time + ""); while (lock == 0) { TimeUnit.MILLISECONDS.sleep(50); lock = jedis.setnx(key, time + ""); } //设置超时时间 jedis.expire(key, 3); } //自己的业务逻辑处理 } catch (Exception e) { throw new RuntimeException(e); } finally { if (jedis != null) { jedis.del(key); jedis.close(); } } } }
示例中以用户id为key加锁:不同用户访问该方法的时候不会排斥等待
锁机制的实现利用了Redis的setnx方法:如果数据库里key存在了则不存储数据,返回0
redis的该方法是线程安全的,可以放心使用
aop方式
示例代码
package com.whereta.jedis; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import javax.annotation.Resource; import java.util.Calendar; import java.util.Date; import java.util.concurrent.TimeUnit; /** * Created by vincent on 15-10-14. */ @Aspect @Component public class JedisLockAop { @Resource private JedisPool jedisPool; @Around("execution(public * com.heli.core.pay.soaservice.impl.*.*(..))") public Object serviceAOP(ProceedingJoinPoint point) { Object proceed = null; Jedis jedis = jedisPool.getResource(); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.MILLISECOND, 0); Date calendarTime = calendar.getTime(); long time = calendarTime.getTime(); //请求参数数组 Object[] args = point.getArgs(); //key可以自定义 String key = JedisLock.CacheName.ADD_BEAN_AFTER_CHECK_LOCK_KEY + ":" + args[0]; try { if (jedis != null) { Long lock = jedis.setnx(key, time + ""); while (lock == 0) { TimeUnit.MILLISECONDS.sleep(50); lock = jedis.setnx(key, time + ""); } //设置超时时间 jedis.expire(key, 3); } //用户业务处理 proceed = point.proceed(); return proceed; } catch (Throwable throwable) { throw new RuntimeException(throwable); } finally { if (jedis != null) { jedis.del(key); jedis.close(); } } } }
使用Spring Aop的环绕方法
具体key值可以自定义涉及,譬如:ip,时间等
标签:
原文地址:http://my.oschina.net/vincentzhao/blog/517109