ASP源码.NET源码PHP源码JSP源码JAVA源码DELPHI源码PB源码VC源码VB源码Android源码

Redis分布式锁Java实现

来源:网络整理     时间:2016-03-14     关键词:

本篇文章主要介绍了"Redis分布式锁Java实现",主要涉及到方面的内容,对于Javajrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播感兴趣的同学可以参考一下: Redis分布式锁Java实现redis分布式锁可以解决多个应用进程间同步操作的一致性。网上有很多资料并不能完全解决,PHP版的可以参考 http://www...

Redis分布式锁Java实现

redis分布式锁可以解决多个应用进程间同步操作的一致性。网上有很多资料并不能完全解决,PHP版的可以参考
http://www.cnblogs.com/it-cen/p/4984272.html

  • 1.时间同步问题
  • 2.在一个进程crash后失效时间后自动释放锁
  • 3.有些多线程race condition没有考虑到

Java版本的代码参考如下

package com.wdzj.jedis.distribution.test;

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisException;

/**
 * Jedis实现分布式锁
 * 
 * @author 三文鱼
 *
 */publicclassJedisDistributionLock {privatefinalstaticlong ACCQUIRE_LOCK_TIMEOUT_IN_MS = 10 * 1000;

    privatefinalstaticint EXPIRE_IN_SECOND = 5;//锁失效时间privatefinalstaticlong WAIT_INTERVAL_IN_MS = 100;

    privatefinal JedisPool jedisPool;
    privatefinallong acquireLocktimeoutInMS;
    privatefinalint expireInSecond;
    privatefinallong waitIntervalInMS;
    privatefinal ConcurrentMap settedKeys;

    publicJedisDistributionLock(final JedisPool jedisPool,
            finallong acquireLocktimeout, finalint expireInSecond,
            finallong waitIntervalInMS) {
        this.jedisPool = jedisPool;
        this.acquireLocktimeoutInMS = acquireLocktimeout;
        this.expireInSecond = expireInSecond;
        this.waitIntervalInMS = waitIntervalInMS;
        this.settedKeys = new ConcurrentHashMap();
    }

    publicJedisDistributionLock(final JedisPool jedisPool) {
        this(jedisPool, ACCQUIRE_LOCK_TIMEOUT_IN_MS, EXPIRE_IN_SECOND,
                WAIT_INTERVAL_IN_MS);
    }

    publicvoidlock(final String redisKey) throws Exception {
        validateRedisKeyName(redisKey);
        Jedis resource = null;
        try {
            resource = jedisPool.getResource();
            long timeoutAt = currentTimeMillisFromRedis()
                    + acquireLocktimeoutInMS;
            boolean flag = false;
            while (true) {
                String expireAt = String.valueOf(currentTimeMillisFromRedis()
                        + expireInSecond * 1000);
                long ret = resource.setnx(redisKey, expireAt);
                if (ret == 1) {
                    settedKeys.put(redisKey, expireAt);
                    flag = true;
                    break;
                } else {
                    String oldExpireAt = resource.get(redisKey);
                    if (oldExpireAt != null
                            && Long.parseLong(oldExpireAt) < currentTimeMillisFromRedis()) {
                        oldExpireAt = resource.getSet(redisKey, expireAt);

                        if (Long.parseLong(oldExpireAt) < currentTimeMillisFromRedis()) {
                            settedKeys.put(redisKey, expireAt);

                            flag = true;
                            break;
                        } else {
                            // loop ...
                        }
                    } else {
                        // loop ...
                    }
                }

                if (acquireLocktimeoutInMS <= 0
                        || timeoutAt < currentTimeMillisFromRedis()) {
                    break;
                }

                try {
                    TimeUnit.MILLISECONDS.sleep(waitIntervalInMS);
                } catch (Exception ignore) {
                }
            }
            if (!flag) {
                thrownew RuntimeException("canot acquire lock now ...");
            }
        } catch (JedisException je) {
            je.printStackTrace();
            if (resource != null) {
                jedisPool.returnBrokenResource(resource);
            }
            throw je;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (resource != null) {
                jedisPool.returnResource(resource);
            }
        }
    }

    publicbooleanunlock(final String name) throws Exception {
        validateRedisKeyName(name);
        Jedis resource = null;
        try {
            resource = jedisPool.getResource();
            resource.del(name);
            settedKeys.remove(name);
            returntrue;
        } catch (JedisException je) {
            je.printStackTrace();
            if (resource != null) {
                jedisPool.returnBrokenResource(resource);
            }
            returnfalse;
        } catch (Exception e) {
            e.printStackTrace();
            returnfalse;
        } finally {
            if (resource != null) {
                jedisPool.returnResource(resource);
            }
        }
    }

    publicbooleanunlockAll() throws Exception {
        Jedis resource = null;
        try {
            resource = jedisPool.getResource();
            Iterator iter = settedKeys.keySet().iterator();
            while (iter.hasNext()) {
                String key = iter.next();
                resource.del(key);
                settedKeys.remove(key);
            }
            returntrue;
        } catch (JedisException je) {
            je.printStackTrace();
            if (resource != null) {
                jedisPool.returnBrokenResource(resource);
            }
            returnfalse;
        } catch (Exception e) {
            e.printStackTrace();
            returnfalse;
        } finally {
            if (resource != null) {
                jedisPool.returnResource(resource);
            }
        }
    }

    privatevoidvalidateRedisKeyName(String name) {
        if (name == null || "".equals(name.trim())) {
            thrownew IllegalArgumentException("validateKey fail.");
        }
    }

    private Long currentTimeMillisFromRedis() throws Exception {
        Jedis resource = null;
        try {
            resource = jedisPool.getResource();
            return Long.parseLong(resource.time().get(0)) * 1000;
        } catch (JedisException je) {
            je.printStackTrace();
            if (resource != null) {
                jedisPool.returnBrokenResource(resource);
            }
            throw je;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (resource != null) {
                jedisPool.returnResource(resource);
            }
        }
    }

    publicstaticvoidmain(String[] args) throws Exception {
        ExecutorService executorService = Executors.newCachedThreadPool();
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxIdle(200);
        config.setMaxTotal(200);
        JedisPool pool = new JedisPool(config, "192.168.8.21", 6379, 3000,
                "########");
        final JedisDistributionLock jedisDistributionLock = new JedisDistributionLock(
                pool);

        finalint threadNum = 8;
        final CountDownLatch countDownLatch = new CountDownLatch(threadNum);
        finalint reqsPerThread = 10;
        final AtomicLong seq = new AtomicLong(0);
        final String key = "qq";

        for (int i = 0; i < threadNum; i++) {
            executorService.submit(new Runnable() {
                publicvoidrun() {
                    System.out.println(Thread.currentThread().getId()
                            + " start...");
                    try {
                        for (int j = 0; j < reqsPerThread; j++) {
                            jedisDistributionLock.lock(key);
                            System.out.println(seq.incrementAndGet());
                            jedisDistributionLock.unlock(key);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        countDownLatch.countDown();
                    }
                }

            });
        }

        countDownLatch.await();

        System.out.println("---------------------------->" + seq.longValue());
        if (threadNum * reqsPerThread == seq.longValue()) {
            System.out.println("-------------ok-----------");
        } else {
            System.err.println("-------------err-----------");
        }
    }

}

参考资料
http://www.cnblogs.com/wuhuajun/p/5242644.html

http://www.cnblogs.com/it-cen/p/4984272.html

').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('
  • ').text(i)); }; $numbering.fadeIn(1700); }); });

    以上就介绍了Redis分布式锁Java实现,包括了方面的内容,希望对Javajrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播有兴趣的朋友有所帮助。

    本文网址链接:http://www.codes51.com/article/detail_433455.html

    相关图片

    相关文章