Java线程锁&分布式锁的理解及应用
了解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线程锁&分布式锁的理解及应用的更多相关文章
- Java 线程安全 与 锁
Java 线程安全 与 锁 多线程内存模型 线程私有栈内存 每个线程 私有的内存区域 进程公有堆内存 同一个进程 共有的内存区域 为什么会有线程安全问题? 多个线程同时具有对同一资源的操作权限,又发生 ...
- Java使用Redisson分布式锁实现原理
本篇文章摘自:https://www.jb51.net/article/149353.htm 由于时间有限,暂未验证 仅先做记录.有大家注意下哈(会尽快抽时间进行验证) 1. 基本用法 添加依赖 &l ...
- 【Thread】java线程之对象锁、类锁、线程安全
说明: 1.个人技术也不咋滴.也没在项目中写过线程,以下全是根据自己的理解写的.所以,仅供参考及希望指出不同的观点. 2.其实想把代码的github贴出来,但还是推荐在初学的您多亲自写一下,就没贴出来 ...
- Java线程安全与锁优化,锁消除,锁粗化,锁升级
线程安全的定义 来自<Java高并发实战>"当多个线程访问一个对象的时候,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方法的时候进行任何 ...
- Java线程安全与锁优化
线程安全的严谨定义: 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交题执行,也不需要进行额外的同步,或者调用方法进行其他任何操作,调用这个对象的行为都可以或者正确的结果,那么这 ...
- 【Java线程安全】锁
Java都有哪些锁? synchronized 和 reentranlock是最常见的,其中前者又JVM提供实现,后者有专门对应的java.util.concurrent包提供:同时后者功能更加丰富. ...
- Java线程同步与锁
一.synchronized synchronized锁什么?锁对象.可能锁对象包括: this, 临界资源对象,Class类对象. 1,同步方法 synchronized T methodName( ...
- java实现Redis分布式锁
网上到处都是分布式锁的代码,基本都是通过setNX 和 expire 这两个不是原子操作,肯定会有问题,不乏好多人通过用setNX的value当做过期时间来弥补等等.但是好像都不太好,或者多少有点问题 ...
- 终极锁实战:单JVM锁+分布式锁
目录 1.前言 2.单JVM锁 3.分布式锁 4.总结 =========正文分割线================= 1.前言 锁就像一把钥匙,需要加锁的代码就像一个房间.出现互斥操作的场景:多人同 ...
随机推荐
- React-Native 之 常用组件Image使用
前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...
- win、mac系统配置本地电脑ip为域名教程
win系统: 如何修改hosts文件 主机文件原内容如下: #Copyright(c)1993-2009 Microsoft Corp. # #这是Windows的Microsoft TCP / IP ...
- 深入理解HashMap(及hash函数的真正巧妙之处)
原文地址:http://www.iteye.com/topic/539465 Hashmap是一种非常常用的.应用广泛的数据类型,最近研究到相关的内容,就正好复习一下.网上关于hashmap的文章很多 ...
- LongAdder类学习笔记
优秀原文 LongAdder | LongAccumulator简介 源码阅读:全方位讲解LongAdder 说到LongAdder,不得不提的就是AtomicLong.AtomicLong是JDK1 ...
- Merkle Tree(默克尔树)算法解析
Merkle Tree概念 Merkle Tree,通常也被称作Hash Tree,顾名思义,就是存储hash值的一棵树.Merkle树的叶子是数据块(例如,文件或者文件的集合)的hash值.非叶节点 ...
- Linux 下开发环境的搭建(软件安装)
一.Centos6.5下安装JDK 步骤1: 查看现有安装的JDK版本 rpm –qa | grep -i java 步骤2: 卸载已有软件 rpm -e --nodeps java-1.7.0-op ...
- pomelo 安装
1. 安装nodejs ,python ,C++运行环境(VS2012以上版本) 2.npm install -g node-gyp --registry=https://registry.npm.t ...
- servlet文件下载实例剖析
package mypack; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; ...
- MVC框架定义
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码 ...
- GPS数据包格式及数据包解析
GPS数据包解析 GPS数据包解析 目的 GPS数据类型及格式 数据格式 数据解释 解析代码 结构体定义 GPRMC解析函数 GPGGA解析函数 测试样例输出 gps数据包格式 gps数据解析 车联网 ...