时间:2021-05-19
复制代码 代码如下:
package com.happyelements.odin.util;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jetbrains.annotations.NotNull;
import com.happyelements.odin.jedis.JedisClient;
import com.happyelements.rdcenter.commons.util.DateTimeUtil;
/**
* User: jude.wang
* Date: 14-1-16
* Time: 上午9:43
*/
public class ConcurrentUtil {
public static final String USER_LOCK_KEY_FORMAT = "user_lock_%d_%s";
public static final String CUSTOM_LOCK_FORMAT = "custom_lock_%s";
public static final JedisClient redisClient = JedisClient.getInstance();
public static final String UNLOCKED = "0";
public static final String LOCKED = "1";
private static final int MAX_REPEAT_TIMES = 10;
@NotNull
public static String buildUserLockKey(long userId, @NotNull String key) {
checkNotNull(key);
return String.format(USER_LOCK_KEY_FORMAT, userId, key);
}
@NotNull
public static String buildCustomLockKey(@NotNull String key) {
checkNotNull(key);
return String.format(CUSTOM_LOCK_FORMAT, key);
}
/**
* 此方法可以因为拿不到锁而导致operation没有执行
*
* @param key
* @see com.happyelements.odin.util.ConcurrentUtil#buildCustomLockKey(String)
* @see com.happyelements.odin.util.ConcurrentUtil#buildUserLockKey(long, String)
*
* @param operation
* @throws com.happyelements.odin.util.ConcurrentUtil.OperationNotExecException
* operation没有被执行
*/
public static void doJobWithLock(@NotNull String key, @NotNull ILockOperation operation) throws OperationNotExecException {
boolean locked = false;
try {
checkNotNull(key);
checkNotNull(operation);
locked = lock(key);
} catch (Throwable t) {
throw new OperationNotExecException(key, t);
}
try {
if (locked) {
// System.out.println(Thread.currentThread() + "\t" + "lock");
operation.doJob();
} else {
throw new OperationNotExecException(key);
}
} finally {
if (locked) {
unlock(key);
}
}
}
private static void unlock(String key) {
try {
checkNotNull(key);
String oldStatus = redisClient.getSet(key, UNLOCKED);
if (isUnlocked(oldStatus)) {
// lock->doJob->过期->unlock
// TODO LOG
}
} catch (Throwable t) {
// TODO LOG
}
// System.out.println(Thread.currentThread() + "\t" + "unlock");
}
private static boolean isUnlocked(String status) {
return status == null || status.equals(UNLOCKED);
}
private static boolean lock(String key) {
boolean locked = false;
for (int i = 0; i < MAX_REPEAT_TIMES; i++) {
String oldStatus = redisClient.getSet(key, LOCKED);
if (isUnlocked(oldStatus)) {
if (oldStatus == null) {
redisClient.expire(key, DateTimeUtil.MINUTE_SECOND * 5);
locked = true;
break;
}
locked = true;
break;
}
}
return locked;
}
public static interface ILockOperation {
void doJob();
}
/**
* {@link com.happyelements.odin.util.ConcurrentUtil.ILockOperation#doJob()}没有被执行
* 上层必须处理该异常,捕获到该异常可以retry本次操作,或者包装成{@link com.happyelements.rdcenter.commons.throwable.HeException} 抛出去
*/
public static class OperationNotExecException extends Exception {
public OperationNotExecException() {
}
public OperationNotExecException(String s) {
super(s);
}
public OperationNotExecException(String s, Throwable throwable) {
super(s, throwable);
}
public OperationNotExecException(Throwable throwable) {
super(throwable);
}
}
}
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
目标:优化代码,利用多进程,进行近实时预处理、网络预测及后处理:本人尝试了pytorch的multiprocessing,进行多进程同步处理以上任务。fromt
在初步了解Python多进程之后,我们可以继续探索multiprocessing包中更加高级的工具。这些工具可以让我们更加便利地实现多进程。进程池进程池(Pro
本文实例讲述了PHP实现的多进程控制。分享给大家供大家参考,具体如下:自己写了个多进程控制的框架代码,留着备查declare(ticks=1);function
一下代码通过协程、多线程、多进程的方式,运行代码展示异步与同步的区别。importgeventimportthreadingimportmultiprocess
本文实例讲述了python进程池实现的多进程文件夹copy器。分享给大家供大家参考,具体如下:应用:文件夹copy器(多进程版)importmultiproce