本次使用
java.util.function.Consumer;
java.util.function.Function;
java.util.function.Predicate;
java.util.function.Supplier;
借助redis做一个简单的分布式锁。
废话不多说,直接上代码,如果想了解java.util.function自己去百度吧,大都说的非常清楚,我就在这废话了。
工具包代码:
@Slf4j
@Component
public class Locks {
@Autowired
RedisTemplate<String, String> redisTemplate;
public <R> R supplier(String key, Supplier<R> fun) {
log.info("获取分布式锁: {}", key);
try {
if (!redisTemplate.opsForValue().setIfAbsent(key, "1")) {
throw new ServiceException(RestStatus.THREE_ERROR);
}
return fun.get();
} finally {
redisTemplate.delete(key);
}
}
@Transactional
public <R> R supplierInTransaction(Supplier<R> fun) {
return fun.get();
}
public <T, R> R function(String key, T t, Function<T, R> fun) {
log.info("获取分布式锁: {}", key);
try {
if (!redisTemplate.opsForValue().setIfAbsent(key, "1")) {
throw new ServiceException(RestStatus.THREE_ERROR);
}
return fun.apply(t);
} finally {
redisTemplate.delete(key);
}
}
@Transactional
public <T, R> R functionInTransaction(T t, Function<T, R> fun) {
return fun.apply(t);
}
public <T, R> void consumer(String key, T t, Consumer<T> fun) {
log.info("获取分布式锁: {}", key);
try {
if (!redisTemplate.opsForValue().setIfAbsent(key, "1")) {
throw new ServiceException(RestStatus.THREE_ERROR);
}
fun.accept(t);
} finally {
redisTemplate.delete(key);
}
}
@Transactional
public <T, R> void consumerInTransaction(T t, Consumer<T> fun) {
fun.accept(t);
}
public <T, R> Boolean predicate(String key, T t, Predicate<T> fun) {
log.info("获取分布式锁: {}", key);
try {
if (!redisTemplate.opsForValue().setIfAbsent(key, "1")) {
throw new ServiceException(RestStatus.THREE_ERROR);
}
return fun.test(t);
} finally {
redisTemplate.delete(key);
}
}
@Transactional
public <T, R> Boolean predicateInTransaction(T t, Predicate<T> fun) {
return fun.test(t);
}
@Transactional
public void action(String key, Runnable runnable) {
log.info("获取分布式锁: {}", key);
try {
if (!redisTemplate.opsForValue().setIfAbsent(key, "1")) {
throw new ServiceException(RestStatus.THREE_ERROR);
}
runnable.run();
} finally {
redisTemplate.delete(key);
}
}
}
工具包使用:
@RestController
@Slf4j
@RequestMapping("/test")
public class TestLocksController {
@Autowired
Locks locks;
@GetMapping("/supplier")
public String supplier() {
return locks.supplier("supplier", () -> {
log.info("supplier =>>>>>>>>");
return "supplier";
});
}
@GetMapping("/consumer")
public void consumer(Session session) {
locks.consumer("consumer", session, (x) -> {
log.info("consumer =>>>>>>>>session:{}", session);
});
}
@GetMapping("/predicate")
public Boolean predicate(Session session) {
return locks.predicate("predicate", session, (x) -> {
log.info("predicate =>>>>>>>>session:{}", session);
return true;
});
}
@GetMapping("/function")
public Session function(Session session) {
return locks.function("function", session, (x) -> {
log.info("function =>>>>>>>>session:{}", session);
return session;
});
}
## 如果需要控制事务:
@GetMapping("/function_t")
public Session functionT(Session session) {
return locks.function("functionT", session, (x) ->
locks.functionInTransaction(session, fun -> {
log.info("functionT =>>>>>>>>session:{}", session);
return session;
}));
}
# locks下的所有方法都不是互斥的,方法是可以随意组合嵌套的,function下可以使用predicate或者其他方法 或 predicateTransaction等其Transaction方法,例如:
@GetMapping("/consumerIn_t")
public String consumerInTransaction() {
return locks.supplier("consumerIn_t", () -> {
locks.consumerInTransaction("consumerIn_t",(x) -> {
log.info("运行事务方法 =>>>>>>>>");
});
return "consumerIn_t";
});
}
}
当前工具包还有很多其他方式的组合使用,这里不一一列举,同时java.util.function的使用在此也只是一种使用方式。

网友评论