基于redis实现的分布式锁

我们知道,在多线程环境中,锁是实现共享资源互斥访问的重要机制,以保证任何时刻只有一个线程在访问共享资源。锁的基本原理是:用一个状态值表示锁,对锁的占用和释放通过状态值来标识,因此基于redis实现的分布式锁主要依赖redis的SETNX命令和DEL命令,SETNX相当于上锁,DEL相当于释放锁,当然,在下面的具体实现中会更复杂些。之所以称为分布式锁,是因为客户端可以在redis集群环境中向集群中任一个可用Master节点请求上锁(即SETNX命令存储key到redis缓存中是随机的)。

现在相信你已经对在基于redis实现的分布式锁的基本概念有了解,需要注意的是,这个和前面文章提到的使用WATCH 命令对key值进行锁操作没有直接的关系。java中synchronized和Lock对象都能对共享资源进行加锁,下面我们将学习用java实现的redis分布式锁。

java中的锁技术

在分析java实现的redis分布式锁之前,我们先来回顾下java中的锁技术,为了直观的展示,我们采用“多个线程共享输出设备”来举例。

不加锁共享输出设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class LockTest {
    //不加锁
    static class Outputer {
        public void output(String name) {
            for(int i=0; i<name.length(); i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println();
        }
    }
    public static void main(String[] args) {
        final Outputer output = new Outputer();
        //线程1打印zhangsan
        new Thread(new Runnable(){
            @Override
            public void run() {
                while(true) {
                     try{
                         Thread.sleep(1000);
                     }catch(InterruptedException e) {
                         e.printStackTrace();
                     }
                     output.output("zhangsan");
                }  
            }
        }).start();
         
        //线程2打印lingsi
        new Thread(new Runnable(){
            @Override
            public void run() {
                while(true) {
                     try{
                         Thread.sleep(1000);
                     }catch(InterruptedException e) {
                         e.printStackTrace();
                     }
                     output.output("lingsi");
                }
            }
        }).start();
         
        //线程3打印wangwu
        new Thread(new Runnable(){
            @Override
            public void run() {
                while(true) {
                     try{
                         Thread.sleep(1000);
                     }catch(InterruptedException e) {
                         e.printStackTrace();
                     }
                     output.output("huangwu");
                }
            }
        }).start();
    }
}

上面例子中,三个线程同时共享输出设备output,线程1需要打印zhangsan,线程2需要打印lingsi,线程3需要打印wangwu。在不加锁的情况,这三个线程会不会因为得不到输出设备output打架呢,我们来看看运行结果:

1
2
3
4
5
6
7
8
9
10
11
huangwu
zhangslingsi
an
huangwu
zlingsi
hangsan
huangwu
lzhangsan
ingsi
huangwu
lingsi

  

从运行结果可以看出,三个线程打架了,线程1没打印完zhangsan,线程2就来抢输出设备......可见,这不是我们想要的,我们想要的是线程之间能有序的工作,各个线程之间互斥的使用输出设备output。

http://www.cnblogs.com/hjwublog/p/5749929.html

https://my.oschina.net/91jason/blog/517996?p=1

基于redis实现的分布式锁的更多相关文章

  1. 基于Redis的简单分布式锁的原理

    参考资料:https://redis.io/commands/setnx 加锁是为了解决多线程的资源共享问题.Java中,单机环境的锁可以用synchronized和Lock,其他语言也都应该有自己的 ...

  2. 一个Redis实现的分布式锁

    import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.conne ...

  3. redis客户端、分布式锁及数据一致性

    Redis Java客户端有很多的开源产品比如Redission.Jedis.lettuce等. Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持:Redis ...

  4. 基于zookeeper实现高性能分布式锁

    实现原理:利用zookeeper的持久性节点和Watcher机制 具体步骤: 1.创建持久性节点 zkLock 2.在此父节点下创建子节点列表,name按顺序定义 3.Java程序获取该节点下的所有顺 ...

  5. Redis系列(二)--分布式锁、分布式ID简单实现及思路

    分布式锁: Redis可以实现分布式锁,只是讨论Redis的实现思路,而真的实现分布式锁,Zookeeper更加可靠 为什么使用分布式锁: 单机环境下只存在多线程,通过同步操作就可以实现对并发环境的安 ...

  6. redis系列:分布式锁

    redis系列:分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...

  7. Redis高并发分布式锁详解

    为什么需要分布式锁 1.为了解决Java共享内存模型带来的线程安全问题,我们可以通过加锁来保证资源访问的单一,如JVM内置锁synchronized,类级别的锁ReentrantLock. 2.但是随 ...

  8. 基于redis的简易分布式爬虫框架

    代码地址如下:http://www.demodashi.com/demo/13338.html 开发环境 Python 3.6 Requests Redis 3.2.100 Pycharm(非必需,但 ...

  9. 基于zookeeper实现的分布式锁

    基于zookeeper实现的分布式锁 2011-01-27 • 技术 • 7 条评论 • jiacheo •14,941 阅读 A distributed lock base on zookeeper ...

随机推荐

  1. Guzz

    http://www.cnblogs.com/shitou/archive/2011/05/31/2064838.html

  2. 什么是MBR?(含图解)

    Mbr位于磁盘的0柱面,0磁头,1扇区. MBR       有三部分构成,主引导程序,硬盘分区表DPT和,硬盘的有效标志55AA.在512个字节的主引导扇区里. 主引导程序占446个字节,dpt占6 ...

  3. PHP的基础计算器

    设计一个计算的功能,该功能能够完成运算并且能够对不合理的数据进行验证并且给出错误提示. 规则: 第一个数,第二个数不能够为空 如果操作符是/,第二个数数不能够为0. <?php header(' ...

  4. style、currentStyle、getComputedStyle区别介绍

    style.currentStyle.getComputedStyle区别介绍 来自:蓝色天空 样式表有三种方式 内嵌样式(inline Style) :是写在Tag里面的,内嵌样式只对所有的Tag有 ...

  5. Android 核心组件 Activity 之上

    核心组件的特征 1. 必须继承自特定的类(Activity 或者 Activity的子类) 2. 必须注册: 通常是AndroidManifest.xml的 <application> 中 ...

  6. 好用的ssh工具oh-my-zsh / iterm2

    The manual way 1. Clone the repository: git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh- ...

  7. linux内核编译,内核参数修改

    核心(kernel):/boot/vmlinuz-version version 带发行包版本,本地版本内核模块(kernel object): /lib/modules/version/ 内核设计: ...

  8. 可变参数列表---以dbg()为例

    在UART驱动的drivers/serial/samsung.h中遇到如下定义: #ifdef CONFIG_SERIAL_SAMSUNG_DEBUG extern void printascii(c ...

  9. Sqoop 1.99.4 安装

    1.安装准备工作:已经装好的 hadoop 环境是 hadoop-2.5.1 64位下载的sqoop安装包(注意是hadoop200)http://www.us.apache.org/dist/sqo ...

  10. Fedora 17下安装Oracle 10g详细图文教程

    一.硬件要求——内存 & swap & 硬盘 最小内存与swap: 1 GB of RAM & swap 建议内存与swap: 2 GB of RAM & swap [ ...