美文网首页
redis实现分布式锁

redis实现分布式锁

作者: 守住阳光 | 来源:发表于2018-11-14 17:52 被阅读0次

    一、什么是线程安全

            当多个线程访问某个类时,不管运行时环境采用何种类,调度方式或者这些线程将如何交替执行,并且在主要代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么这个类就是线程安全的。

            锁的使用能使并行执行的代码变成串行执行,从而实现线程安全。

    二、如何优化锁?

            1、缩小锁的范围。

            2、减小锁的粒度。

            3、使用锁分段技术。

    三、锁的种类

            1、公平锁:synchronized,ReentrantLock。

            2、非公平锁:ReentrantLock,CAS(主要用于竞争量不大的情况,不要用在竞争激烈的情况)。

            3、独享锁:synchronized,ReentrantLock。

            4、共享锁:semaphore。

    四、一个分布式锁需要满足的特性

            1、互斥性

            在任意时刻只有一个客户端可以获取锁。

            2、防死锁

            即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续客户端能加锁,加一个有效时间。

            3、持锁人解锁

            加锁和解锁必须是同一个客户端,客户端不能把别人加的锁给解了。

            4、可重入

            当一个客户端获取锁对象之后,这个客户端可以再次获取该对象上的锁。

    五、加锁解锁的流程

    加解锁流程

     六、分布式锁的算法实现

    分布式锁的算法实现

    七、上代码

    public class RedisDistributedLock implements Lock{

            private ThreadLocal<String> lockContext = new  ThreadLocal<String> ();

            private long time = 100 ;

            private Thread exclusiveOwnerThread ;

            public  RedisDistributedLock (){

            }

            //阻塞式获取锁

            public void lock() {

                    while(!tryLock()){

                            try{

                                Thread.sleep(time);

                            }catch(InterruptedException e){

                                e.printStrackStace();

                            }

                    }

            }

            public boolean tryLock(){

                    return  tryLock(time , TimeUnit.MILLSECOND);

            }

            private boolean  tryLock(long time , TimeUnit  timeUnit){

                    String id = UUID.randomUUID().toString();

                    Thread t = thread.currentThread();

                    Jedis jedis = RedisClient.getClient();

                    if(jedis.setnx("redis",id)==1){

                            jedis.pexpire( "redis" , timeUnit.toMills(time) );

                            lockContext.set(id);

                            setExclusiveOwnerThread(t);

                            return true;

                    }else if( exclusiveOwnerThread==t  ){

                            return true;

                    }

                    return false;

            }

            public void unLock(){

                    String script = null;

                    try{

                        Jedis jedis =  RedisClient.getClient();

                         script  = inputStream2String(getClass().getSourceAsStream("/redis. script "));

                        if(lockContext.get()==null){

                                return ;

                        }

                        jedis.eval( script, Arrays.asList("redis"), Arrays.asList(lockContext.get()) );    

                        lockContext.remove();

                    }catch(Exception e){

                          e.printStrackTrace();

                    }

            }

            public void lockInterruptibly() throws InterruptedException{

                    if(Thread.interrupted())

                        throws  new InterruptedException ();

                    while(! tryLock()){

                         Thread.sleep(time);

                    }

            }

            private String  inputStream2String (InputStream in) throws IOException{

                    StringBuffer out = new  StringBuffer();

                    byte[] b = new  byte[1024];

                    for(int n;(n=in.read(b))!=-1;){

                            out.append(new String(0,n));

                    }

                    return out.toString();

            }

    }

    相关文章

      网友评论

          本文标题:redis实现分布式锁

          本文链接:https://www.haomeiwen.com/subject/elvjfqtx.html