标签:
普通方式
直接看代码
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