当前位置: 移动技术网 > IT编程>开发语言>Java > redis实现多进程数据同步工具代码分享

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

2019年07月22日  | 移动技术网IT编程  | 我要评论

复制代码 代码如下:

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网