同一进程

重入锁

使用ReentrantLock获取锁的时候回判断当前线程是否为获取锁的线程,如果是则将同步的状态+1,释放锁的时候则将状态-1,只有将同步状态的次数置为0的时候才会是最终释放锁。

读写锁

使用ReentrantReadWriteLock,同时维护一对锁:读锁和写锁。当写线程访问时则其他所有锁都将阻塞,读线程访问时则不会。通过读写锁的分离可以很大程度的提高并发量和吞吐量。

不同进程

分布式锁:
基于数据库

可以创建一张表,将其中的某个字段设置为唯一索引,当多个请求过来的时候只有新建记录成功的请求才算获取到锁,当使用完毕删除这条记录的时候即释放锁。

存在的问题:

----数据库单点问题,挂了怎么办?

----不是重入锁,同一进程无法在释放锁之前再次获得锁,因为数据库中已经存在了一条记录了。

----锁是非阻塞的,一旦insert失败就会立即返回,并不会进入阻塞队列只能下一次再次获取。

----锁没有失效时间,如果那个进程解锁失败那就没有请求可以再次获取锁了。

解决方案:
----数据库切换为主从,不存在单点

----在表中加入一个同步状态字段,每次获取锁的时+1,释放锁的时候-1,当状态为0的时候就删除这条记录,即释放锁。

----非阻塞的情况可以用while循环来实现,循环的时候记录时间,达到x秒记为超时,break。

----可以开启一个定时任务每隔一段时间扫描找出多少x秒都没有被删除的记录,主动删除这条记录。

基于redis

使用setNX(key) setEX(timeout)命令,只有在该key不存在的时候创建这个key,就相当于获取了锁,由于超时时间,所以过了规定时间就会自动删除,这样也可以避免死锁。

基于zookeeper

Java中使用到的锁的更多相关文章

  1. Java中的双重检查锁(double checked locking)

    最初的代码 在最近的项目中,写出了这样的一段代码 private static SomeClass instance; public SomeClass getInstance() { if (nul ...

  2. 5000字 | 24张图带你彻底理解Java中的21种锁

    本篇主要内容如下: 本篇文章已收纳到我的Java在线文档. Github 我的SpringCloud实战项目持续更新中 帮你总结好的锁: 序号 锁名称 应用 1 乐观锁 CAS 2 悲观锁 synch ...

  3. Java中可重入锁ReentrantLock原理剖析

    本文由码农网 – 吴极心原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 一. 概述 本文首先介绍Lock接口.ReentrantLock的类层次结构以及锁功能模板类AbstractQue ...

  4. 深度解析Java中的那把锁

    锁的本质 我们先来讨论锁的出现是为了解决什么问题,锁要保证的事情其实很好理解,同一件事(一个代码块)在同一时刻只能由一个人(线程)操作. 这里所说的锁为排他锁,暂不考虑读写锁的情况 我们在这里打个比方 ...

  5. java中的12种锁

    java中很多地方会涉及到锁,比如java代码并发场景,DB中的并发场景,分布式中的锁....你知道几种呢?下面来看看常见的11种锁 1. 乐观锁/悲观锁 这两个概念是人们对java中各种锁总结提出的 ...

  6. 全面了解Java中的15种锁概念及机制!

    在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 1.公平锁 / 非公平锁 2.可重入锁 / 不可重入锁 3.独享锁 / 共享锁 4.互斥锁 / 读 ...

  7. Java 中常见的细粒度锁实现

    上篇文章大致说了下 ReentrantLock 类的使用,对 ReentrantLock 类有了初步的认识之后让我们一起来看下基于 ReentrantLock 的几种细粒度锁实现. 这里我们还是接着用 ...

  8. java中redis的分布式锁工具类

    使用方式 try { if(PublicLock.getLock(lockKey)){ //这里写代码逻辑,执行完后需要释放锁 PublicLock.freeLock(lockKey); } } ca ...

  9. Java中的公平锁和非公平锁实现详解

    前言 Java语言中有许多原生线程安全的数据结构,比如ArrayBlockingQueue.CopyOnWriteArrayList.LinkedBlockingQueue,它们线程安全的实现方式并非 ...

随机推荐

  1. [luogu1552][派遣]

    题目链接 思路 首先肯定要树形dp,一直没想到怎么用左偏树.如果不断弹出又不断地合并复杂度不就太高了.瞄了眼题解才知道可以直接用大根树.然后记录出当前这棵左偏树的大小(树里面所有点的薪水之和)以及点的 ...

  2. malloc() 和 calloc()有啥区别

    calloc()在动态分配完内存后,自动初始化该内存空间为零(会将所分配的内存空间中的每一位都初始化为零). 而malloc()不初始化,里边数据是随机的垃圾数据. calloc(size_t n, ...

  3. c#文件管理

    Directory类-------目录管理 Directory.CreateDirectory(_Path); bool IsExit=Directory.Exists(_Path); Directo ...

  4. MySQL准备

    目录 数据库管理软件的由来 什么是数据? 什么是数据库管理系统/软件? 数据库管理的三个阶段 MySQL 概述SQL语句 安装MySQL(在命令行的操作全要用管理员权限) 将MySQL服务制作为win ...

  5. Javascript鼠标键盘事件

    鼠标事件click:单击dblclick:双击mousedown:鼠标按下mouseup:鼠标抬起mouseover:鼠标悬浮mouseout:鼠标离开mousemove:鼠标移动mouseenter ...

  6. jmeter中判断数据库是否存在相应的记录

    jmeter判断数据库中是否存在相应记录可以使用count 配合case,然后再加个断言,后面用 变量JMeterThread.last_sample_ok来判断是否存在相应记录 select cas ...

  7. Systemd 添加自定义服务(开机自启动)

    Systemd 简介:https://fedoraproject.org/wiki/Systemd/zh-cn 一.service unit 常用命令,以 mysql 服务为例 # 开机启动 syst ...

  8. Hadoop记录-Hadoop监控指标汇总

    系统参数监控metrics load_one            每分钟的系统平均负载 load_fifteen        每15分钟的系统平均负载 load_five           每5 ...

  9. ruby数组操作方法汇总

    1.数组定义 arr1 = [] arr2 = Array.new arr3 = ['1','2','3'] 2.输出 print arr3,"\n" #123 puts arr3 ...

  10. 错误记录:vue跟vue编译器版本不一致

    错误如下: error in ./src/Utils.vue Module build failed: Error: Vue packages version mismatch: - vue@ - v ...