Synchronized 和 Lock锁的区别
* 1、 Synchronized 是内置的关键字,Lock是一个Java接口
* 2、 Synchronized 无法判断获取锁的状态,Lock可以判断是否获取到了锁
* 3、 Synchronized 会自动释放锁,Lock锁必须要手动释放锁!如果不释放锁,会死锁
* 4、 Synchronized 线程1(获得锁,阻塞)、线程2(等待,一直傻傻的等);
* Lock锁就不一定会等待下去了.因为lock.tryLock();会尝试获取锁,等不到就结束了
* 5、 Synchronized是一个可重入锁,不可以中断的,非公平的
* Lock是可一个重入锁,可以判断锁,可以自己设置是否公平
* 6、 Synchronized适合锁少量的代码同步问题,Lock适合锁大量的同步问题
其实在工作中很少用到Java提供的锁,当需要用到锁的时候,我们是通过Redis来上锁的。
```java
/**
* Desc:如果使用业务key获取lockKey,那么在业务key的基础上加一个 lock: 前缀
* tK, templateKey
* values,待填充值
*/
public static String getLockK(String tK, String... values) {
return lockPre.concat(getK(tK, values));
}
/**
* Desc:通过模板和待填充值封装真实key
* tK, templateKey
* values,待填充值
*/
public static String getK(String tK, String... values) {
String placeHolder = tK.split(c)[3];
String [] templates = placeHolder.split(splitMultiValue);
//key自定义处理
if (isSelfDefine) {
try {
if (selfDefine == null) pkgMap();
if (selfDefine != null && selfDefine.containsKey(tK)) {
tK = selfDefine.get(tK)[0].concat(c).concat(placeHolder);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
if (values != null && values.length > 0) {
for (int i = 0; i < values.length; i ++) {
if (templates.length > i && StrUtil.isNotBlank(templates[i])) {
tK = tK.replaceFirst(templates[i], String.valueOf(values[i]));
} else {
break;
}
}
} else {
if (templates.length == 1 && templatePlaceholder.concat(PLACEHOLDER.PLID.toString()).concat(templatePlaceholder).equals(templates[0]))
tK = tK.replaceFirst(templates[0], PLACEHOLDER.PLID.toString());
}
return tK;
}
/**
* 获取锁并设置等待时间
*
* @param key 锁
* @param waitTime 等待时间 秒
* @return
*/
public boolean lock(String key, int waitTime) {
RLock lock = redissonClient.getLock(key);
boolean ret = false;
try {
ret = lock.tryLock(waitTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
ret = false;
Thread.currentThread().interrupt();
}
return ret;
}
// 使用案例:
String lockKey = RedisKeyUtils.getLockK(RedisKeyUtils.COMMON_LOCK_T, "initPriceReview-" + stepId);
try {
if (redisUtils.lock(lockKey, 15)) {
// 业务代码
}
}
```