1. 分布式锁
1. 加锁(保证原子操作)
- set key value nx ex seconds
2. 解锁
- del key
package com.bytedance.lms.redis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.params.SetParams;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.UUID;
public class DistributedLockTest {
private String key, value;
private String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
public DistributedLockTest(String lockName) {
this.key = lockName;
}
public static JedisPool initRedis() {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(8);
config.setMaxTotal(8);
config.setMaxWaitMillis(1000);
JedisPool jedisPool = new JedisPool(config, "127.0.0.1", 6379, 10000, null, 0);
return jedisPool;
}
public void lock(long expiredTime) {
try (Jedis jedis = initRedis().getResource()) {
while (true) {
value = UUID.randomUUID().toString().trim().replaceAll("-", "");
String result = jedis.set(key, value, SetParams.setParams().nx().px(expiredTime));
if ("OK".equals(result)) {
break;
}
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void unlock() {
try (Jedis jedis = initRedis().getResource()) {
List<String> keys = Arrays.asList(new String[]{key});
List<String> values = Arrays.asList(new String[]{value});
jedis.eval(script, keys, values);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
DistributedLockTest lock = new DistributedLockTest("lock:vote");
System.out.println("尝试加锁......");
lock.lock(1000 * 5);
System.out.println("加锁成功......");
try {
System.out.println("修改票数: " + Thread.currentThread().getName());
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
System.out.println("解锁成功");
}
}
}).start();
}
}
}
- 结果