sql并发 锁 优化思路

在高负载多线程应用程序中,性能非常重要。 开发人员必须意识到并发问题才能获得更好的性能。 当我们需要并发时,我们通常拥有必须由两个或更多线程共享的资源。

在这种情况下,我们处于竞争状态 ,其中只有一个线程(在资源上)将获取锁,而所有其他需要该锁的线程将被阻塞。 此同步功能不是免费提供的。 JVM和OS都会消耗资源,以便为您提供有效的并发模型。 使并发实现资源密集的三个最基本的因素是:

  • 上下文切换
  • 内存同步
  • 封锁

为了编写优化的代码进行同步,您必须了解这三个因素以及如何减少它们。 编写此类代码时,您必须注意许多事项。 在本文中,我将向您展示一种通过减小锁的粒度来减少这些因素的技术。

从基本规则开始: 不要将锁持有超过必要的时间。

获取锁之前 ,请做任何您需要做的事情, 仅将锁用于对同步资源进行操作并立即释放它。 看一个简单的例子:

public class HelloSync {private Map dictionary = new HashMap();public synchronized void borringDeveloper(String key, String value) {long startTime = (new java.util.Date()).getTime();value = value + "_"+startTime;dictionary.put(key, value);System.out.println("I did this in "+((new java.util.Date()).getTime() - startTime)+" miliseconds");}
}

在此示例中,我们违反了基本规则,因为我们创建了两个Date对象,调用System.out.println()并执行许多String连接。 唯一需要同步的动作是动作:“ dictionary.put(key,value); ”更改代码并将同步从方法范围移到这一行。 更好的代码是这样的:

public class HelloSync {private Map dictionary = new HashMap();public void borringDeveloper(String key, String value) {long startTime = (new java.util.Date()).getTime();value = value + "_"+startTime;synchronized (dictionary) {dictionary.put(key, value);}System.out.println("I did this in "+((new java.util.Date()).getTime() - startTime)+" miliseconds");}
}

上面的代码可以写得更好,但是我只想给你个想法。 如果想知道如何做,请检查java.util.concurrent.ConcurrentHashMap 。

那么,如何减少锁的粒度呢? 简而言之,通过尽可能少地请求锁。 基本思想是使用单独的锁来保护一个类的多个独立状态变量,而不是在类范围内仅具有一个锁。 看看我在许多应用程序中看到的这个简单示例。

public class Grocery {private final ArrayList fruits = new ArrayList();private final ArrayList vegetables = new ArrayList();public synchronized void addFruit(int index, String fruit) {fruits.add(index, fruit);}public synchronized void removeFruit(int index) {fruits.remove(index);}public synchronized void addVegetable(int index, String vegetable) {vegetables.add(index, vegetable);}public synchronized void removeVegetable(int index) {vegetables.remove(index);}
}

杂货店老板可以在他的杂货店添加水果和蔬菜/从中删除水果和蔬菜。 杂货店的这种实现使用基本的杂货店锁来保护水果和蔬菜,因为同步是在方法范围内完成的。 除了这个胖锁,我们可以使用两个单独的守护程序,每种资源(水果和蔬菜)使用一个。 检查下面的改进代码。

public class Grocery {private final ArrayList fruits = new ArrayList();private final ArrayList vegetables = new ArrayList();public void addFruit(int index, String fruit) {synchronized(fruits) fruits.add(index, fruit);}public void removeFruit(int index) {synchronized(fruits) {fruits.remove(index);}}public void addVegetable(int index, String vegetable) {synchronized(vegetables) vegetables.add(index, vegetable);}public void removeVegetable(int index) {synchronized(vegetables) vegetables.remove(index);}
}

使用两个防护装置(拆分锁)后,我们看到的锁定流量将少于原始的胖锁。 当我们将其应用于具有中等锁争用的锁时,此技术会更好地工作。 如果我们将其应用于具有轻微争用的锁,则收益很小,但仍为正值。 如果我们将其应用于争用较大的锁,则结果并不总是更好,您必须意识到这一点。

请出于良心使用此技术。 如果您怀疑这是一个严重的争用锁,请按照以下步骤操作:

  • 确认您的生产需求量,将其乘以3或5(即使您愿意准备,甚至乘以10)。
  • 根据新流量在测试平台上运行适当的测试。
  • 比较两个解决方案,然后选择最合适的解决方案。

有更多技术可以提高同步性能,但是对于所有技术,基本规则是: 保持锁的时间不要超过必要的时间

正如我已经向您解释的那样,此基本规则可以翻译为“尽可能少地寻求锁”,也可以翻译为其他翻译(解决方案),我将在以后的文章中尝试描述它们。

另外两个重要建议:

  • 请注意java.util.concurrent包(和子包) 中的类,因为它们有非常聪明和有用的实现。
  • 通过使用良好的设计模式,大多数时候并发代码可以最小化。 始终牢记企业集成模式 ,它们可以节省您的时间。

参考: 减少锁粒度– Java,集成和源代码的优点,来自我们JCG合作伙伴 Adrianos Dadis的并发优化 。

相关文章 :
  • Java并发教程–信号量
  • Java并发教程–重入锁
  • Java并发教程–线程池
  • Java并发教程–可调用,将来
  • Java并发教程–阻塞队列
  • Java并发教程– CountDownLatch
  • Java Fork / Join进行并行编程
  • Java内存模型-快速概述和注意事项
  • Java教程和Android教程列表

翻译自: https://www.javacodegeeks.com/2011/10/concurrency-optimization-reduce-lock.html

sql并发 锁 优化思路

sql并发 锁 优化思路_并发优化–减少锁粒度相关推荐

  1. 【Matlab】智能优化算法_蜻蜓优化算法DA

    [Matlab]智能优化算法_蜻蜓优化算法DA 1.背景介绍 2.灵感 3.公式推导 3.1 勘探和开发操作 4.算法流程图 5.文件结构 6.伪代码 7.详细代码及注释 7.1 DA.m 7.2 d ...

  2. 【Matlab】智能优化算法_蚁狮优化算法ALO

    [Matlab]智能优化算法_蚁狮优化算法ALO 1.背景介绍 2.基本思想 3.公式推导 3.1 ALO算法的运算符 3.2 蚂蚁的随机游动 3.3 困在蚂蚁坑里 3.4 修建陷阱 3.5 蚂蚁划向 ...

  3. 【Matlab】智能优化算法_灰狼优化算法GWO

    [Matlab]智能优化算法_灰狼优化算法GWO 1.背景介绍 2.基本思想 2.1 等级制度 2.2 狩猎方式 3.公式推导 3.1 社会等级制度 3.2 包围猎物 3.3 包围猎物 3.4 攻击猎 ...

  4. oracle 10g 速度慢,让Oracle跑得更快—Oracle 10g性能分析与优化思路_数据库教程

    资源名称:让Oracle跑得更快-Oracle 10g性能分析与优化思路 内容简介: 在这本书里读者将会学到作者在性能优化方面的一些思路和思考,一些故障处理的方法和原则,这些东西是作者在实践中长期积累 ...

  5. 多重背包单调队列优化思路_动态规划入门——多重背包与单调优化

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法与数据结构的第14篇文章,也是动态规划专题的第三篇. 在之前的文章当中,我们介绍了多重背包的二进制拆分的解法.在大多数情况下,这种 ...

  6. sql自定义函数学习思路_学习SQL:用户定义的函数

    sql自定义函数学习思路 You can create several user-defined objects in a database. One of these is definitely u ...

  7. 增删改查操作下锁的相关情况_查询时的锁分析

    此系列主要分析在增删改查操作下,表是否有索引等情况下,锁的申请使用情况,研究分析并用于语句调优,数据库优化,死锁堵塞分析等:由于时间问题,该篇只分析查询的情况,下篇继续分析 锁的种类 首先,先了解下数 ...

  8. java锁性能对比_提高Java的锁性能

    java锁性能对比 Plumbr是唯一可以通过解释应用程序性能数据来自动检测Java性能问题根本原因的解决方案. 几个月前,我们在Plumbr中引入了锁定线程检测之后,我们开始收到类似于"嘿 ...

  9. mysql乐观锁与事务_[数据库事务与锁]详解七: 深入理解乐观锁与悲观锁

    注明: 本文转载自http://www.hollischuang.com/archives/934 在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库 ...

最新文章

  1. AjaxControlToolkit中CalendarExtender日历控件的用法
  2. “编译器错误信息: CS0016: 未能写入输出文件”解决方法
  3. Python编程语言学习:sklearn.manifold的TSNE函数的简介、使用方法、代码实现之详细攻略
  4. c51语言if语句多条件使用,单片机if语句判断多个条件
  5. 大学计算机基础毕业论文操作步骤,大学计算机基础教学论文
  6. Linux的实际操作:文件目录类的实用指令(帮助指令 man help)
  7. pdo oracle返回参数游标,PDOStatement::closeCursor
  8. 中科院单细胞分析算法开发博士带你做单细胞转录组分析
  9. 列表合并变种题,map()函数扩展
  10. Pb(96) The serializable class Model does not declare a static final serialVersionUID field of typ...
  11. 如何查询以太信道接口_浅谈百兆千兆以太网物理层
  12. 超棒的30款JS类库和工具
  13. 2020 年,嵌入式开发工程师的两大必知必会!
  14. Yahoo Programming Contest 2019 E - Odd Subrectangles
  15. php 豆瓣api_豆瓣网api使用方式
  16. Android屏幕共享与直播-red5流媒体服务器搭建
  17. linux降低交叉编译器版本,嵌入式ARM+Linux 多個不同版本的交叉編譯器的切換方法...
  18. Windows调试技巧工具
  19. 产品生命周期管理展望
  20. Arduino | 由八按键控制的俄罗斯方块

热门文章

  1. Servlet使用适配器模式进行增删改查案例(DeptServiceImpl.java)
  2. Mysql字符串截取 mysql将字符串字段转为数字排序或比大小
  3. python 高维数据_Python数据分析入门|利用NumPy高效处理高维数据
  4. java异常了还会往下走吗_异常一个问题,请帮下忙:处理异常后,程序会继续往下运行吗...
  5. micrometer_具有InlfuxDB的Spring Boot和Micrometer第3部分:Servlet和JDBC
  6. 设计模式 工厂方法_工厂方法设计模式
  7. spring依赖注入_Spring依赖注入
  8. zuul过滤器_Zuul 2 –样本过滤器
  9. openhub_介绍OpenHub框架
  10. tomcat默认连接数_Tomcat的默认连接器