了解Java线程锁之前,先理解线程和进程的定义。进程是操作系统分配资源(CPU)的基本单位,线程是CPU执行的基本单位,一个进程可拥有多个线程,同进程间的多个线程共享分配给进程的资源。比如启动JVM时,会拥有一个进程,JVM处理并发请求的线程共享JVM的堆内存资源。

  进程间的通信:网络通信,比如RPC,MQ,Socket。

  线程间的通信:由于多线程共享地址空间和数据空间,因此同进程间的多个线程的通信是任意线程数据可以直接提供其他线程使用,而不必通过操作系统。

  Java线程的状态:初始(New),运行(Runnable),阻塞(Blocked),等待(Waiting),超时等待(Time_Waiting),终止(Teminate)。

  1. 初始:新创建的一个线程对象,但还没有调用start()方法。

  2. 运行:Java线程中将就绪(ready)和运行中(Running)俩种状态笼统称为“运行”。

  3. 阻塞:表示线程阻塞于锁。

  4. 等待:进入该状态的线程需要其他线程作出一些特定动作(通知或中断)来激活或结束。

  5. 超时等待:该状态等同于Waiting,它可以在制定的时间内自行返回,比如sleep()方法。

  6. 终止:表示该线程已经执行完毕

  通过线程的6大状态,能看出线程锁主要出现在阻塞(Blocked),什么情况下会用到线程锁?比如并发情况下为了控制资源争抢问题或者实现互斥效果,会进行locked,也就是把并发控制为同步。

  既然线程锁已能实现同步控制,为什么还要衍生出分布式锁?因为所谓的线程锁解决的是同一个进程中的并发锁问题,不同进程中存在资源可见性的问题。进程间的资源是不共享的,也就是不可见的。比如在不同端口启动多个JVM(多个进程),它们之间的共享资源(内存)和线程锁都是互不可见的。从而分布式系统中,也是在分布在不同机器中,同进程的线程锁是无法控制并发问题的。

  分布式锁应该具备的条件:

  1. 在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行; 
  2. 高可用的获取锁与释放锁; 
  3. 高性能的获取锁与释放锁; 
  4. 具备可重入特性; 
  5. 具备锁失效机制,防止死锁; 
  6. 具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败。

  如何在分布式系统中解决最基本的资源争抢或者数据覆盖的问题,理论上来说解决此问题,最基本需解决锁可见性的问题,也就是共享资源。比如基于数据库的锁机制,基于缓存(redis)的分布式锁,以及基于zookeeper实现的分布式锁。

  1. 基于数据库的锁机制实现的分布式锁

  作为数据库本身已有一套健全的锁机制(更新),同时是基于外部的磁盘存储的逻辑(另外一个进程),完全符合分布式锁的需求,但由于锁资源存储在磁盘中,需进行I/O操作,因此相对来说性能不高。

  比如:select * from tb_lock where id = 3 for update,当执行这个语句时,数据库会自动对id=3这一行数据加行级锁(id为主键,否则为表级锁),其它事务必须等待此次事务提交或回滚后才能执行。

  2. 基于缓存(redis)实现的分布式锁

  由于redis的单进程单线程的原理,同时也时外部缓存的存储逻辑,也是能作为分布式锁的底层基础。同时expire的过期功能,又完美的解决了特殊原因导致锁无法释放的问题。

  github上的redisson开源项目已实现了分布式锁功能,同时也解决了redis的重入锁问题。也可通过LUA脚本+redis实现单线程事务控制。

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

  基于zookeeper临时有序节点的大致思想:每个客户端对某个方法加锁时,在zookeeper上的与该方法对应指定节点的目录下,生成一个唯一的瞬时节点。判断是否获取锁的逻辑是只需要判断有序节点序号最小的一个。当释放锁的时,只需将这个瞬时节点删除即可。同时,其可避免服务宕机导致的锁无法释放,而产生的死锁问题。

  

Java线程锁&分布式锁的理解及应用的更多相关文章

  1. Java 线程安全 与 锁

    Java 线程安全 与 锁 多线程内存模型 线程私有栈内存 每个线程 私有的内存区域 进程公有堆内存 同一个进程 共有的内存区域 为什么会有线程安全问题? 多个线程同时具有对同一资源的操作权限,又发生 ...

  2. Java使用Redisson分布式锁实现原理

    本篇文章摘自:https://www.jb51.net/article/149353.htm 由于时间有限,暂未验证 仅先做记录.有大家注意下哈(会尽快抽时间进行验证) 1. 基本用法 添加依赖 &l ...

  3. 【Thread】java线程之对象锁、类锁、线程安全

    说明: 1.个人技术也不咋滴.也没在项目中写过线程,以下全是根据自己的理解写的.所以,仅供参考及希望指出不同的观点. 2.其实想把代码的github贴出来,但还是推荐在初学的您多亲自写一下,就没贴出来 ...

  4. Java线程安全与锁优化,锁消除,锁粗化,锁升级

    线程安全的定义 来自<Java高并发实战>"当多个线程访问一个对象的时候,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方法的时候进行任何 ...

  5. Java线程安全与锁优化

    线程安全的严谨定义: 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交题执行,也不需要进行额外的同步,或者调用方法进行其他任何操作,调用这个对象的行为都可以或者正确的结果,那么这 ...

  6. 【Java线程安全】锁

    Java都有哪些锁? synchronized 和 reentranlock是最常见的,其中前者又JVM提供实现,后者有专门对应的java.util.concurrent包提供:同时后者功能更加丰富. ...

  7. Java线程同步与锁

    一.synchronized synchronized锁什么?锁对象.可能锁对象包括: this, 临界资源对象,Class类对象. 1,同步方法 synchronized T methodName( ...

  8. java实现Redis分布式锁

    网上到处都是分布式锁的代码,基本都是通过setNX 和 expire 这两个不是原子操作,肯定会有问题,不乏好多人通过用setNX的value当做过期时间来弥补等等.但是好像都不太好,或者多少有点问题 ...

  9. 终极锁实战:单JVM锁+分布式锁

    目录 1.前言 2.单JVM锁 3.分布式锁 4.总结 =========正文分割线================= 1.前言 锁就像一把钥匙,需要加锁的代码就像一个房间.出现互斥操作的场景:多人同 ...

随机推荐

  1. c++ 类的构造顺序

    在单继承的情况下,父类构造先于子类,子类析构先于父类,例: class A { public: A() { cout << "A" << endl; } ~ ...

  2. static, const 和 static const 变量的初始化问题

    const 常量的在超出其作用域的时候会被释放,但是 static 静态变量在其作用域之外并没有释放,只是不能访问. static 修饰的是静态变量,静态函数.对于类来说,静态成员和静态函数是属于整个 ...

  3. Django-ORM简介

    ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...

  4. 微软Holographic将更名为Windows Mixed Reality

    微软Holographic将更名为Windows Mixed Reality ----世界变化好快.  还没来得及细细品味,它就已经更名了. 程序员的焦虑,处在一个信息大爆炸的年代,大数据,云计算,机 ...

  5. android studio 解决avd启动问题 ----waiting for target device come online

    android studio 模拟器打不开,一直停留在第三方.waiting for target  device  come online 问题解决方法 方法1.Android Emulator 未 ...

  6. WordPress“无法将上传的文件移动至wp-content/uploads/”的解决办法

    WordPress“无法将上传的文件移动至wp-content/uploads/”的问题在有些配置不完善的虚拟主机或服务器中会碰到,一般会出现以下症状:1.无论是从文章编辑页面还是媒体库页面都无法上传 ...

  7. Metronic4.7.5 下载 HTML5 UI后台管理框架

    Metronic 是一套精美的响应式后台管理模板,基于强大的 Twitter Bootstrap 3.3.4 框架实现.Metronic 拥有简洁优雅的 Metro UI 风格界面,6 种颜色可选,7 ...

  8. 解决ASP.NET MVC(post数据)Json请求太大,无法反序列化(The JSON request was too large to be deserialized)

    这个问题出现的场景并不是很多,当你向服务端异步(ajax)post数据非常大的情况下(比如做权限管理的时候给某个角色分配权限那么就可能会出现,我所遇到的就是该角色大概200个模块每个模块平均2个功能- ...

  9. 【LOJ】#2562. 「SDOI2018」战略游戏

    题解 圆方树建好之后点是原来的两倍,而st表求lca也要开到点的两倍,所以是四倍 我并没有开小,然而= =,我的预处理log2,写成了200000,而不是400000 我是不是折翼啊= = 很可写,我 ...

  10. WIN8+VS2013编写发布WCF、一(编写)、二(部署)、三(调用)

    原文://http://www.cnblogs.com/tntboom/p/4348483.html 引言:上学期因为写服务器用WCF,所以连查资料再瞎调试勉强成功了,但是这学期又到了用WCF的时候, ...