import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.FutureTask; import org.springframework.util.Assert; /****************************** * 创建日期: 2013-9-1 上午9:24:59 * 创建作者:yh.li ([email protected]) * 类名称 :ConcurentFutureTaskUtil.java * 版 本: * 功 能: * 最后修改: * 修改记录: *****************************************/ public class ConcurrentFutureTaskUtil { private static final int MODULE_SIZE = 10; @SuppressWarnings("unchecked") private static final ConcurrentMap<String, FutureTask<?>>[] MAPS = new ConcurrentHashMap[MODULE_SIZE]; static { for (int i = 0; i < MODULE_SIZE; i++) { MAPS[i] = new ConcurrentHashMap<String, FutureTask<?>>(); } } public static <V> V submitTaskAndGetResult(String key, Callable<V> callable) { Assert.notNull(key, "submitTaskAndGetResult() param key cann't be null"); Assert.notNull(futureTask, "submitTaskAndGetResult() param callable cann't be null"); return submitTaskAndGetResult(key, new FutureTask<V>(callable)); } @SuppressWarnings("unchecked") private static <V> V submitTaskAndGetResult(String key, FutureTask<V> futureTask) { ConcurrentHashMap<String, FutureTask<?>> concurrentHashMap = getConcurrentMap(key); try { FutureTask<?> f = concurrentHashMap.putIfAbsent(key, futureTask); if (f == null) { f = futureTask; f.run(); } V result = null; try { result = (V) f.get(); } catch (Exception e) { throw new RuntimeException(e.getCause()); } return result; } finally { concurrentHashMap.remove(key); } } private static ConcurrentHashMap<String, FutureTask<?>> getConcurrentMap(String key) { long hashCode = (long) key.hashCode(); hashCode = Math.abs(hashCode); int moudleNum = (int) hashCode % MODULE_SIZE; return (ConcurrentHashMap<String, FutureTask<?>>) MAPS[moudleNum]; } }
import java.util.Calendar; import java.util.Date; import java.util.Random; import java.util.concurrent.TimeUnit; import com.xx.xx.cache.memcache.MemcachedCache; /****************************** * 版权所有:xx 所有权利 * 创建日期: 2013-11-23 下午12:25:11 * 创建作者:xx * 类名称 :ScheduledTaskUtil.java * 版 本: * 功 能: * 最后修改: * 修改记录: *****************************************/ public class ScheduledTaskUtil { static Random random = new Random(); /** * 该方法用于在分布式环境中,定时任务执行,每个任务只执行一次 * @param cache memcached实现 * @param timeCacheKey 时间缓存key * @param runnable 任务 * @param delay 任务执行间隔 * @param timeUnit 时间单位 */ public static void schedule(MemcachedCache cache, String timeCacheKey, Runnable runnable, int delay, TimeUnit timeUnit) { Date now = new Date(); int second = (int) timeUnit.toSeconds(delay); java.util.Calendar calendar = java.util.Calendar.getInstance(); calendar.setTime(now); calendar.add(Calendar.SECOND, second); if (cache.add(timeCacheKey, calendar.getTime(), second)) { sleep(); runnable.run(); }else{ Date latestDate = (Date) cache.get(timeCacheKey); if (latestDate != null) { if (latestDate.before(now)) { //可能会重复 cache.put(timeCacheKey, calendar.getTime(), second); sleep(); runnable.run(); } } } } private static void sleep(){ try { TimeUnit.SECONDS.sleep(random.nextInt(30)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }
import java.util.concurrent.TimeUnit; import com.xx.xx.cache.memcache.MemcachedCache; /****************************** * 版权所有:xx * 创建日期: 2013-12-9 下午7:40:16 * 创建作者:xx * 类名称 :MemcacheLock.java * 版 本: * 功 能: * 最后修改: * 修改记录: *****************************************/ public class SimpleMemcacheLock { public static boolean lock(MemcachedCache cache, String lockKey, long lockTime, TimeUnit timeUnit) { int secend = (int) timeUnit.toSeconds(lockTime); if (secend <= 0) throw new IllegalArgumentException("lockTime must be greeter than 0"); boolean hasLocked = false; while (!hasLocked) { hasLocked = cache.add(lockKey, "1", secend); if (hasLocked) { break; } else { try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } } return hasLocked; } public static void unLock(MemcachedCache cache, String lockKey) { cache.remove(lockKey); } public static boolean tryLock(MemcachedCache cache, String lockKey, long lockTime, TimeUnit timeUnit) { int secend = (int) timeUnit.toSeconds(lockTime); if (secend <= 0) throw new IllegalArgumentException("lockTime must be greeter than 0"); return cache.add(lockKey, "1", secend); } }