<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>ziyou</artifactId>
<version>0.0.1</version>
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.2</version>
</dependency>
</dependencies>
</project>
package com.test.ziyou.common;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
public class JedisManager {
private static JedisPool jedisPool;
static{
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(100);
config.setMaxIdle(10);
config.setMinIdle(0);
jedisPool = new JedisPool(config,"10.47.229.190",6379);
}
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
package com.test.ziyou.lock.distributed;
import com.test.ziyou.common.JedisManager;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by ~~
* 2019/6/3.
*/
public class RedisLock {
public static void main(String[] args) {
testMultiThreadLock();
}
public static void testMultiThreadLock(){
int threadCount = 10;
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 4);
String key = "user:add";
//超时时间
int expire = 1;
for (int i = 0; i < threadCount; i++) {
executorService.execute(() -> {
try {
String lock = RedisLock.tryLock(key, expire);
if (null != lock) {
System.out.println(Thread.currentThread().getName() + "获得锁");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "释放锁");
RedisLock.release(key, lock);
} else {
System.out.println(Thread.currentThread().getName() + "获得锁失败");
}
} catch (Exception e) {
e.printStackTrace();
}
});
}
executorService.shutdown();
}
public static String tryLock(String key, int expire) {
String lockValue = null;
try (Jedis jedis = JedisManager.getJedis()) {
long end = System.currentTimeMillis() + expire;
while (System.currentTimeMillis() < end) {
lockValue = UUID.randomUUID().toString();
Long setnx = jedis.setnx(key, lockValue);
System.out.println(Thread.currentThread().getName() + " 3333 setnx = " + setnx + " , lockValue = " + lockValue);
if (1 == setnx) {
jedis.expire(key, expire);
return lockValue;
}
if (-1 == jedis.ttl(key)) {
jedis.expire(key, expire);
}
}
}
return null;
}
public static boolean release(String key, String value) {
try (Jedis jedis = JedisManager.getJedis()) {
while (true) {
jedis.watch(key);
if (value.equals(jedis.get(key))) {
Transaction transaction = jedis.multi();
jedis.del(key);
List<Object> exec = transaction.exec();
if (null == exec) {
continue;
}
return true;
}
jedis.unwatch();
break;
}
}catch (Exception e){
e.printStackTrace();
}
return false;
}
}
package com.test.ziyou.lock.distributed;
import com.test.ziyou.common.JedisManager;
import redis.clients.jedis.Jedis;
import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
/**
* Created by ~~
* 2019/6/3.
*/
public class RedisLock2 {
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final Long RELEASE_SUCCESS = 1L;
/**
* 尝试获取分布式锁
* @param jedis Redis客户端
* @param lockKey 锁
* @param requestId 请求标识
* @param expireTime 超期时间
* @return 是否获取成功
*/
public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
return LOCK_SUCCESS.equals(result);
}
/**
* 释放分布式锁
* @param jedis Redis客户端
* @param lockKey 锁
* @param requestId 请求标识
* @return 是否释放成功
*/
public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
return RELEASE_SUCCESS.equals(result);
}
public static void main(String[] args) {
//要创建的线程的数量
CountDownLatch looker = new CountDownLatch(1);
CountDownLatch latch = new CountDownLatch(10);
final String key = "lockKey";
for (int i = 0; i < latch.getCount(); i++) {
Jedis jedis = JedisManager.getJedis();
UUID uuid = UUID.randomUUID();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
looker.await();
System.out.println(Thread.currentThread().getName() + "竞争资源,获取锁");
boolean getResult = tryGetDistributedLock(jedis, key, uuid.toString(), 5000);
if (getResult) {
System.out.println(Thread.currentThread().getName() + "获取到了锁,处理业务,用时3秒");
Thread.sleep(3000);
boolean releaseResult = releaseDistributedLock(jedis, key, uuid.toString());
if (releaseResult) {
System.out.println(Thread.currentThread().getName() + "业务处理完毕,释放锁");
}
} else {
System.out.println(Thread.currentThread().getName() + "竞争资源失败,未获取到锁");
}
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
}
try {
System.out.println("准备,5秒后开始");
Thread.sleep(5000);
looker.countDown(); //发令 let all threads proceed
latch.await(); // // wait for all to finish
System.out.println("结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* https://www.cnblogs.com/love-wzy/p/10190514.html
*/
/**
* 准备,5秒后开始
*/
/**
* 准备,5秒后开始
* Thread-1竞争资源,获取锁
* Thread-6竞争资源,获取锁
* Thread-9竞争资源,获取锁
* Thread-5竞争资源,获取锁
* Thread-3竞争资源,获取锁
* Thread-4竞争资源,获取锁
* Thread-2竞争资源,获取锁
* Thread-10竞争资源,获取锁
* Thread-8竞争资源,获取锁
* Thread-7竞争资源,获取锁
* Thread-3竞争资源失败,未获取到锁
* Thread-6竞争资源失败,未获取到锁
* Thread-8竞争资源失败,未获取到锁
* Thread-1竞争资源失败,未获取到锁
* Thread-4获取到了锁,处理业务,用时3秒
* Thread-9竞争资源失败,未获取到锁
* Thread-10竞争资源失败,未获取到锁
* Thread-5竞争资源失败,未获取到锁
* Thread-2竞争资源失败,未获取到锁
* Thread-7竞争资源失败,未获取到锁
*/
/**
* 准备,5秒后开始
* Thread-1竞争资源,获取锁
* Thread-6竞争资源,获取锁
* Thread-9竞争资源,获取锁
* Thread-5竞争资源,获取锁
* Thread-3竞争资源,获取锁
* Thread-4竞争资源,获取锁
* Thread-2竞争资源,获取锁
* Thread-10竞争资源,获取锁
* Thread-8竞争资源,获取锁
* Thread-7竞争资源,获取锁
* Thread-3竞争资源失败,未获取到锁
* Thread-6竞争资源失败,未获取到锁
* Thread-8竞争资源失败,未获取到锁
* Thread-1竞争资源失败,未获取到锁
* Thread-4获取到了锁,处理业务,用时3秒
* Thread-9竞争资源失败,未获取到锁
* Thread-10竞争资源失败,未获取到锁
* Thread-5竞争资源失败,未获取到锁
* Thread-2竞争资源失败,未获取到锁
* Thread-7竞争资源失败,未获取到锁
* Thread-4业务处理完毕,释放锁
* 结束
*/
}