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.前言 锁就像一把钥匙,需要加锁的代码就像一个房间.出现互斥操作的场景:多人同 ...
随机推荐
- PowerDesigner导出word模版
模板下载 解压至:C:\Program Files (x86)\Sybase\PowerDesigner 15\Resource Files\Report Templates 即可 感谢http:// ...
- 使用PyMongo访问需要认证的MongoDB
Windows 10家庭中文版,Python 3.6.4,PyMongo 3.7.0,MongoDB 3.6.3,Scrapy 1.5.0, 前言 在Python中,使用PyMongo访问Mongod ...
- P2733 家的范围 Home on the Range
又是一校内模拟赛见的题 不知道为什么出题人怎么这么喜欢USACO的Farmer John的他的牛... 感觉这道题不是特别的难,但也不很水 同机房的神仙们都说这个题是一道二维前缀和的裸题,但我当时的确 ...
- WordPress解决优酷、土豆视频移动端观看问题并自适应
转:https://www.xhsay.com/wp-iframe-handler-youku-tudou.html 虽然WordPress能直接插入优酷.土豆的视频但是无法在移动端观看,于是乎笨笨就 ...
- HA下的Spark集群工作原理解密
实验环境: zookeeper-3.4.6 Spark:1.6.0 简介: 本篇博客将从以下几点组织文章: 一:Spark 构建高可用HA架构 二:动手实战构建高可用HA 三:提交程序测试HA 一:S ...
- Java之杨辉三角的实现
今天突然想温习一下Java的基础,想了想就写写杨辉三角吧 1.直接法,利用二维数组 import java.util.Scanner; public class Second { public sta ...
- day1作业二:多级菜单操作
作业二:多级菜单 (1)三级菜单 (2)可以次选择进入各子菜单 (3)所需新知识点:列表.字典 要求:输入back返回上一层,输入quit退出整个程序 思路: (1)首先定义好三级菜单字典: (2)提 ...
- Rookey.Frame之实体类
上周跟大家分享了Rookey.Frame框架的初始化功能,今天继续给大家介绍实体类的设计. 先看下下面菜单实体示例代码: using Rookey.Frame.EntityBase; using Ro ...
- USACO 5.4 Character Recognition
Character Recognition This problem requires you to write a program that performs character recogniti ...
- 更快的速度、更好的服务——易普优APS云排程
众所周知软件执行效率受制于硬件性能,市面上的APS产品多为单机版本,企业要应用好APS,保证紧急插单.计划下发全程无忧,用户电脑硬件性能是不容忽视的一大瓶颈.APS的直接用户是车间管理人员.计划员,而 ...