分布式锁

分布式锁就以zookeeper为例,zookeeper是一个分布式系统的协调器,我们将其理解为一个文件系统,可以在zookeeper服务器中创建或删除文件夹或文件.设D为一个数据系统,不具备事务能力,在并发状态下可能出现对单个数据同时读写.客户端A,B是数据系统D提供的客户端,能够对其读写.

几个关键角色已经登场,D是一个不提供事务行为的数据系统,其存放的数据可被读写,在单客户端条件下可以保证数据的可靠,但是在两个客户端可能并发请求时就变得不可靠,A写的数据可能被B覆盖,B读的数据可能是A没有写完的数据.在不修改D源码为其提供原子性操作的前提下,我们可以考虑分布式锁.

客户端的原始API

void write(){
// 写数据
}
void read(){
// 读数据
}

如何做呢,核心就是以zookeeper为媒介.

修改客户端API,如果读或者写,我们首先要在zookeeper上创建一个文件夹,如果创建成功,我们就执行读写操作,如果不成功(代表已经有人创建了)我们就一直尝试创建,直到创建成功.当创建成功时,对D系统的数据进行读写操作,完成后删除zookeeper上创建的文件夹并退出读写方法.

void write(){
while(在zookeeper上创建文件夹) {
写操作;
删除zookeeper的刚创建的文件夹;
return;
}
}

这样就完成了一个分布式并发行为的同步.假设A已经创建了文件夹,B就没办法进行后续操作,会一直尝试创建文件夹,A执行完操作之后删除文件夹,B才有机会进行在D系统上的操作.这个例子中产生了一个临界资源:D系统的数据,和一个竞态条件:A和B并发读写.(实际上zookeeper中是可以为监听者发送文件情况的,比如我创建文件夹没有成功,可以监听该文件夹,当文件夹变化时会通知你,这时候你就可以再尝试创建文件夹了(很像wait和notify),但是为了不把重心放在zookeeper上就没有改成监听模式)

Java中Synchronized关键字

那我们再回到Java中的synchronized关键字上来,如果你还没理解上面的行为和synchronized的关系你可以继续往后看.

synchronized究竟锁住的是什么呢,锁住的是一块内存,我们在内存中的某个位置设置一个值为0,当该值为0时,一个线程为了修改临界资源将其设置为1,然后读写操作,读写结束将其设置为0,其他线程可以再次将其改为1,进行读写,结束后再将其置为0......这块内存存储在每个对象的对象头中,我们称其为锁标志位(实际上所标志位不是简单的0和1,锁标志位分为四种状态:无锁,偏向锁,轻量级锁,和重量级锁,并发中还涉及锁升级等,但本文不做细究,有兴趣的读者可以查阅相关资料).

当进入synchronized代码块或者方法的时候,你会像上面说的分布式锁那样"创建一个文件夹",其他线程无法"创建文件夹"就会一直去尝试,当代码块或方法结束的时候会"删除文件夹",其他线程可以去抢夺创建文件夹的机会.synchronized可以看做一道门,锁住的对象可以看做是门票.千万不要认为synchronized锁住的是临界资源,synchronized是以某个对象的锁标志作为入场券去约束竞态线程之间行为:我只有一张门票,我只给一个人.

看一下synchronized的用法,多个线程之间的竞态行为一定要是用相同的门票去约束.

// 这锁住的是
class Foo{
// 这锁住的是类对象
static synchronized void bar();
// 这锁住的是this,即实例对象
synchronized void bar();
// 等价于static synchronized
void bar(){
synchronized(Foo.class){};
}
// 等价于synchronized实例方法
void bar(){
synchronized(this){}
}
}

对于静态方法需要注意一点(假如你想观察偏向锁的变化),实例方法可以直接观察实例对象的对象头上的锁标志位,但是静态方法需要观察Foo.class对象的锁标志位,如果观察实例对象的锁标志位会竹篮打水哟.

从分布式锁角度理解Java的synchronized关键字的更多相关文章

  1. Java对象锁和类锁全面解析(多线程synchronized关键字)

    最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不过是别人怎么用就跟着用,并没有搞清楚锁的概念.最近也是遇到一些问题,不搞清楚锁的概念,很容易碰壁,甚至有些时候自己连用没 ...

  2. 【面试普通人VS高手系列】请说一下你对分布式锁的理解,以及分布式锁的实现

    一个工作了7年的Java程序员,私信我关于分布式锁的问题. 一上来就两个灵魂拷问: Redis锁超时怎么办? Redis主从切换导致锁失效怎么办? 我说,别着急,这些都是小问题. 那么,关于" ...

  3. 从源码角度理解Java设计模式——装饰者模式

    一.饰器者模式介绍 装饰者模式定义:在不改变原有对象的基础上附加功能,相比生成子类更灵活. 适用场景:动态的给一个对象添加或者撤销功能. 优点:可以不改变原有对象的情况下动态扩展功能,可以使扩展的多个 ...

  4. java基础Synchronized关键字之对象锁

    java中Synchronized关键字之对象锁    当有多个线程对一个共享数据进行操作时,需要注意多线程的安全问题. 多线程的同步机制对资源进行加锁,使得在同一个时间,只有一个线程可以进行操作,同 ...

  5. Java 多线程 —— synchronized关键字

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  6. Java的synchronized关键字:同步机制总结

    JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块.搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程 ...

  7. 【原创】对Java的synchronized关键字的学习

    在Java中,每一个线程都有一个内部锁.当我们使用synchronized关键字时,就是利用这个内部锁来实现线程对某个对象的锁定控制. 那么,如果某个对象中有两个方法,方法一和方法二都使用了synch ...

  8. Java基础-synchronized关键字的用法(转载)

    synchronized--同步 顾名思义是用于同步互斥的作用的. 这里精简的记一下它的使用方法以及意义: 当synchronized修饰 this或者非静态方法或者是一个实例的时候,所同步的锁是加在 ...

  9. java中synchronized关键字分析

    今天我们来分析一下java中synchronized关键字.首先来看一段java代码:(本地编译环境为mac,jdk1.8的环境) Demo.java package com.example.spri ...

随机推荐

  1. Python3 装逼神器---词云(wordcloud)

    词云 (Word Cloud)是对文本中出现频率较高的词语给予视觉化展示的图形, 是一种常见的文本挖掘的方法. 实例:     依赖包: # pip3 install wordcloud  jieba ...

  2. kail入侵xp实例

    Kali的IP地址是192.168.0.112 Windows XP的IP地址是192.168.0.108 本文演示怎么使用Metasploit入侵windows xp sp3. 启动msfconso ...

  3. mysql 导入sql文件

    navicat 工具导入 1.连接数据库后,右键选择导入sql文件 2.选择sql文件,开始导入 4.过程图 5.结果图

  4. prometheus(6)之常用服务监控

    监控常用服务 1.tomcat 2.redis 3.mysql 4.nginx 5.mongodb prometheus监控tomcat tomcat_exporter地址 https://githu ...

  5. pip 常用命令小结

    pip 常用命令小结 pip这个工具我们经常会用到,毕竟python 是一门以第三方库庞大而著名的编程语言,所以我们总会用pip 安装一些依赖库,当然这只是pip 最常用的一个命令,下面就来介绍一下 ...

  6. MyBatis-Plus 快速入门

    1.简介 MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生. 1.1.特性 无侵入:只做增强不做改变, ...

  7. django improperly configured

    ImproperlyConfigured: You must either define the environment variable DJANGO_SETTINGS_MODULE or call ...

  8. C#窗体学习

    //进度条控件 private void button1_Click(object sender, EventArgs e)        {            int i;            ...

  9. [hdu7034]Array

    令$f(a)_{i}=\min_{i<j\le n,a_{i}=a_{j}}j$​​(特别的,若不存在$j$​​则令$f(a)_{i}=n+1$​​),则有以下性质: 1.对于$b_{i}$​​ ...

  10. [bzoj1741]穿越小行星群

    将每一行/每一列作为一个点,对于一个障碍(x,y),要么第x行和第y列的状态(是否攻击)只需要有一个就可以了,将第x行和第y列连边,就是二分图的最小点覆盖=最大匹配数. 1 #include<b ...