· 7 years ago · Feb 07, 2018, 07:18 AM
1import java.util.UUID;
2import java.util.concurrent.TimeUnit;
3
4/**
5 * Created by huangxx on 2017/6/27.
6 */
7@Service
8@Log4j2
9public class LockKeyService {
10
11 @Autowired
12 private RedisTemplate<String, String> redisTemplate;
13
14 private static final String LOCK_NAME = "LOCK_NAMKE:%s";
15
16 @Override
17 public String getKeyByrequestId(String requestId) {
18 String identifier = acquireLockAndWait(requestId, 2, 5);
19 if (StringUtils.isNotBlank(identifier)) {
20 try {
21 secretKey = generateKey(requestId);
22 dosomething(secretKey);
23 } catch (Exception e) {
24 ......
25 } finally {
26 releaseLock(requestId, identifier);
27 }
28 }
29 return secretKey;
30 }
31
32 /**
33 * @param requestId
34 * @param acquireLockTimeout 获å–é”è¶…æ—¶æ—¶é—´ å•ä½ï¼šs
35 * @param lockTimeout é”过期时间 å•ä½ï¼šs
36 * @return
37 */
38 private String acquireLockWithTimeout(String requestId, long acquireLockTimeout, long lockTimeout) {
39 String identifier = UUID.randomUUID().toString();
40 String lockName = String.format(LOCK_NAME, requestId);
41 long end = System.currentTimeMillis() + acquireLockTimeout * 1000;
42 while (System.currentTimeMillis() < end) {
43 if (redisTemplate.opsForValue().setIfAbsent(lockName, identifier)) {
44 expire(lockName, lockTimeout, TimeUnit.SECONDS);
45 return identifier;
46 }
47 if (redisTemplate.getExpire(lockName) == -1) {
48 expire(lockName, lockTimeout, TimeUnit.SECONDS);
49 }
50 try {
51 Thread.sleep(500);
52 } catch (InterruptedException ie) {
53 log.error("acquireLockWithTimeout thread sleep error!", ie);
54 }
55 }
56 return null;
57 }
58
59 /**
60 * @param requestId
61 * @param waitTime ç‰å¾…æ—¶é—´ å•ä½ï¼šs
62 * @param lockTimeout é”过期时间 å•ä½ï¼šs
63 * @return
64 */
65 private String acquireLockAndWait(String requestId, long waitTime, long lockTimeout) {
66 String identifier = UUID.randomUUID().toString();
67 String lockName = String.format(LOCK_NAME, requestId);
68 if (redisTemplate.opsForValue().setIfAbsent(lockName, identifier)) {
69 expire(lockName, lockTimeout, TimeUnit.SECONDS);
70 return identifier;
71 }
72 if (redisTemplate.getExpire(lockName) == -1) {
73 expire(lockName, lockTimeout, TimeUnit.SECONDS);
74 }
75 try {
76 Thread.sleep(waitTime * 1000);
77 } catch (InterruptedException ie) {
78 log.error("acquireLockAndWait thread sleep error!", ie);
79 }
80 return null;
81 }
82
83 /**
84 * 释放é”ï¼Œåªæœ‰é”å†…å®¹ç¬¦åˆæ—¶æ‰ä¼šé‡Šæ”¾
85 *
86 * @param requestId 用户id
87 * @param identifier é”内容
88 * @return
89 */
90 private boolean releaseLock(String requestId, String identifier) {
91 String lockName = String.format(LOCK_NAME, requestId);
92 while (true) {
93 if (identifier.equals(redisTemplate.opsForValue().get(lockName))) {
94 redisTemplate.delete(lockName);
95 return true;
96 }
97 break;
98 }
99 return false;
100 }
101
102 private String dosomething(String requestId) {
103 ......
104 }
105
106 private void expire(String key, long time, TimeUnit timeUnit) {
107 boolean success = redisTemplate.expire(key, time, timeUnit);
108 while(!success){
109 success = redisTemplate.expire(key, time, timeUnit);
110 }
111 }
112
113}