redis实现多进程数据同步工具代码分享

 更新时间:2014年01月19日 14:38:51   作者:  
这篇文章主要介绍了使用redis实现多进程数据同步工具的代码,大家参考使用吧

复制代码 代码如下:

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);
  }
 }
}

相关文章

  • java组装树形结构List问题

    java组装树形结构List问题

    这篇文章主要介绍了java组装树形结构List问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • java 源码分析Arrays.asList方法详解

    java 源码分析Arrays.asList方法详解

    这篇文章主要介绍了java 源码分析Arrays.asList方法详解的相关资料,需要的朋友可以参考下
    2016-10-10
  • Java之SpringCloud Eurka注册错误解决方案

    Java之SpringCloud Eurka注册错误解决方案

    这篇文章主要介绍了Java之SpringCloud Eurka注册错误解决方案,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • Java调用参数类型是application/x-www-form-urlencoded的API问题

    Java调用参数类型是application/x-www-form-urlencoded的API问题

    在使用Postman进行接口测试时,对于POST请求,需将请求头设置为application/x-www-form-urlencoded,并将参数转为String类型,通常在GET请求中,参数直接拼接在URL后,本文通过具体实例,详细讲解了参数处理的方法,适合API开发者参考
    2024-09-09
  • 基于@Table注解无法使用及报红的解决

    基于@Table注解无法使用及报红的解决

    这篇文章主要介绍了基于@Table注解无法使用及报红的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Java开发必备知识之数组详解

    Java开发必备知识之数组详解

    数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同.本篇文章为大家整理了Java最全关于数组的知识点,并给出其对应的代码,需要的朋友可以参考下
    2021-06-06
  • 详解Java的Struts框架中栈值和OGNL的使用

    详解Java的Struts框架中栈值和OGNL的使用

    这篇文章主要介绍了Java的Struts框架中栈值和OGNL的使用,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
    2015-11-11
  • 详解Java集合中的基本数据结构

    详解Java集合中的基本数据结构

    总有小伙伴让我总结一下Java集合中的基本数据结构的相关知识,今天特地整理了本篇文章,文中有非常详细的介绍,需要的朋友可以参考下
    2021-06-06
  • Java利用位运算实现比较两个数的大小

    Java利用位运算实现比较两个数的大小

    这篇文章主要为大家介绍了,在Java中如何不用任何比较判断符(>,==,<),返回两个数( 32 位整数)中较大的数,感兴趣的可以了解一下
    2022-08-08
  • Java获取本机IP地址的三种方法总结

    Java获取本机IP地址的三种方法总结

    这篇文章主要为大家详细介绍了java获取本机IP地址的三种方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04

最新评论