lock、tryLock和lockInterruptibly的差別:
java中ReentrantLock下有三个获取所得方法:
lock():若lock被thread A取得,thread B会进入block狀態,直到取得lock;
tryLock():若当下不能取得lock,thread就会放弃,可以设置一个超时时间参数,等待多久获取不到锁就放弃;
lockInterruptibly():跟lock()情況一下,但是thread B可以通过interrupt被唤醒处理InterruptedException异常。
在根据业务属性在同一业务中开不同线程进行处理:
private static Map<String,Lock> reentrantLockMap = null;
public static Map<String,Lock> getReentrantLockMap(){
return reentrantLockMap;
}
//初始锁
static{
reentrantLockMap = new HashMap<String,Lock>();
for (DataSyncEntity dataSyncEntity : datList) {
try {
/**根据要处理的表数量初始锁的数量,用于分业务进行上传数据的时候加锁使用**/
Lock newLock2 = new ReentrantLock();
reentrantLockMap.put(dataSyncEntity.getClassName()+"_mysend", newLock2);
}
}
}
//业务中使用锁
public void sendCacheData(){
/*根据系统配置执行不同的方案,
* 配置为1,代表使用原有方案
* (每次定时任务向上级平台发送一条缓存数据
* 配置为2,代表使用新的缓存数据发送方案(根据配置批量发送多条缓存数据)
*/
try {
logger.info(String.format("sendCacheData:发送缓存定时器启动,定时器执行时间:%s", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime())));
if (DataSyncCacheManager.DATA_SYNC_STRATEGY_NEW.equals(dataSyncStrategy)) {
/**2022-6-28修改为定时给每个业务启动上传线程sendCacheData进行数据上传,并且保证单业务的线程安全;**/
if (DataSyncHistoryManager.getDataSync() !=null && DataSyncHistoryManager.getDataSync().getClassNames() != null && DataSyncHistoryManager.getDataSync().getClassNames().size() >0 ) {
for (final DataSyncEntity nowSyncEntity : DataSyncHistoryManager.getDataSync().getClassNames()){
cacheThreadPool.execute(new Runnable(){
@Override
public void run() {
if(null!=DataSyncHistoryManager.getReentrantLockMap()){
//获取上传锁
Lock lock = DataSyncHistoryManager.getReentrantLockMap().get(nowSyncEntity.getClassName()+"_mysend");
//尝试拿到锁
if(null!=lock && lock.tryLock()) {
try {
dataSyncCacheManager.sendData(nowSyncEntity.getClassName());
} catch (Exception e) {
logger.info("同步数据失败" + e.getMessage(),e);
} finally {
lock.unlock();//释放锁
}
}else{
logger.info("获取锁【"+nowSyncEntity.getClassName()+"】失败,稍后继续获取");
}
}
}
});
}
}else{
logger.info("加载上传类异常:"+(null!=DataSyncHistoryManager.getDataSync()?JsonUtil.toJson(DataSyncHistoryManager.getDataSync()):""));
}
} else {
sendData();
}
} catch (Exception e) {
logger.info("启动线程异常:"+e.getMessage(),e);
}
}