java 对象锁定_少锁定Java对象池
java 对象锁定
自从我写任何东西以来已经有一段时间了,我一直在忙于我的新工作,其中涉及在性能调优方面做一些有趣的工作。 挑战之一是减少应用程序关键部分的对象创建。
尽管Java随着时间的推移已改进了GC算法,但垃圾回收打ic一直是Java的主要难题。 Azul是开发无暂停GC的市场领导者,但Azul JVM并非免费!
创建过多的临时/垃圾对象并不能很好地工作,因为它为GC创建了工作,并且将对延迟产生负面影响。 过多的垃圾也不能在多核系统上正常工作,因为它会导致缓存污染。
那么我们应该如何解决呢?
垃圾少编码
仅当您知道需要多少个对象并预先分配它们时,这才有可能,但是实际上很难找到。 但是即使您成功做到了,也必须担心另一个问题
- 您可能没有足够的内存来容纳所需的所有对象
- 您还必须处理并发
那么上述问题的解决方案是什么
有一种对象池设计模式可以解决以上两个问题。 它使您可以指定池中所需的许多对象,并处理并发请求以服务所请求的对象。
对象池一直是许多具有低延迟要求的应用程序的基础。 Flyweight设计模式是对象池的一种风格。
上面的两种模式都将帮助我们避免创建对象。 太好了,因此现在减少了GC工作,并且理论上我们的应用程序性能应该得到改善。 实际上,不会那样做,因为对象池/ Flyweight必须处理并发,并且由于并发问题而失去了避免对象创建而获得的任何优势。
处理并发的最常见方法是什么
对象池是一个典型的生产者/消费者问题,可以使用以下技术来解决:
同步:这是在JDK 1.5之前处理并发的唯一方法。 Apache编写了一个基于同步的出色的对象池 API
锁: Java在JDK 1.5之后增加了对并发编程的出色支持。 已经有一些使用锁来开发对象池的工作,例如, furious-objectpool
无锁:我找不到使用完全无锁技术构建的任何实现,但是furious-objectpool使用ArrayBlocking队列和ConcurrentLinked队列的混合
衡量绩效
在此测试中,我创建了一个包含100万个对象的池,并且这些对象可以通过不同的池实现进行访问,这些对象将从池中取出并返回到池中。
该测试首先从1个线程开始,然后增加线程数以衡量不同池在争用情况下的执行情况
- X轴–螺纹数
- Y轴–以毫秒为单位的时间–越短的时间越好
该测试包括来自Apache的池,Furious池和基于ArrayBlocking的池
Apache的性能最差,并且随着线程数量的增加,性能会进一步下降。 原因是Apache池基于大量使用“同步”
其他两个(基于Furious和ArrayBlocking的池)的性能更好,但是随着争用的增加,它们两者的速度也会降低。
当12个线程试图访问该池时,基于ArrayBlocking队列的池对于100万个项目大约需要1000毫秒。 内部使用Arrayblocking队列的愤怒池大约需要1975 ms。
我必须进行更详细的调查,以找出为什么Furious花费双倍的时间,因为它也是基于ArrayBlocking队列的。
数组阻塞队列的性能不错,但这是一种基于锁定的方法。 如果可以实现无锁池,我们将获得哪种类型的性能?
锁免费游泳池
实现无锁池不是不可能的,但是有点困难,因为您必须处理多个生产者和消费者。
我将实现一个混合池,该池将在生产者端使用锁定,而在消费者端使用非阻塞技术。
让我们看一些数字
我使用新的实现(FastPool)进行了相同的测试,它比ArayBlocking队列快了30%。
30%的改善还不错,它绝对可以帮助我们实现延迟目标。
是什么让快速池快速!
我使用了两种技术来使其快速运行
- 生产者是基于锁的–使用锁来管理多个生产者,这与“数组阻止”队列相同,因此没什么大不了的。
- 立即发布已发布项目–在使用便宜的内存屏障释放锁之前,它会发布元素。 这会有所收获
- 消费者不受阻碍–使用CAS来实现这一目标,消费者永远不会因生产者而受到阻碍。 数组阻止队列阻止使用者,因为它对生产者和使用者使用相同的锁
- 线程局部以保持值的局部性–线程局部用于获取最后使用的值,这在很大程度上减少了争用。
如果您有兴趣查看代码,则可以使用@ FastObjectPool.java
翻译自: https://www.javacodegeeks.com/2013/07/lock-less-java-object-pool.html
java 对象锁定
java 对象锁定_少锁定Java对象池相关推荐
- java方法区对象类型_浅谈Java内存区域与对象创建过程
一.java内存区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则 ...
- java 不能反序列化_不能将“Java.Lang.Studio”实例反序列化到StaskObl对象令牌中
我收到下面的错误消息,有人能帮助或建议如何最好地调试它吗? 无法反序列化的实例 java.lang.String 超出起始值的对象 [来源:(pushbackinputstream)处的令牌;行:1, ...
- JAVA类思维_面向对象思维 Java中的类和对象及其应用
一.面向过程与面向对象 面向过程: 从事务执行者的角度思考问题,我该干什么 重点在过程----事务流程 面向对象: 从事务的指挥者角度思考问题,我应该找谁干什么 重点在对象 面向对象的优点: 1. ...
- java 并发变量_二、Java多线程编程 (对象及变量的并发访问)
非线程安全 多个线程对同一个对象中的实例变量进行并发操作时会出现值被更改.值不同步的情况,进而影响程序的执行流程. 线程安全 线程安全就是获得实例变量的值是经过同步处理的.不会出现被更改不同步的情况. ...
- java数组可以包含对象吗_数组可以包含对象类型的元素吗_对象数组
对象数组就是数组里的每个元素都是类的对象,赋值时先定义对象,然后将对象直接赋给数组就行了. 怎样声明包含 5 个元素的对象数组,每个元素都是 Employee 类型的对象 浏览次数:4875 bill ...
- java 多线程同步_浅谈Java多线程(状态、同步等)
Java多线程是Java程序员必须掌握的基本的知识点,这块知识点比较复杂,知识点也比较多,今天我们一一来聊下Java多线程,系统的整理下这部分内容. 一.Java中线程创建的三种方式: 1.通过继承T ...
- java 多线程同步_详解Java多线程编程中的线程同步方法
1.多线程的同步: 1.1.同步机制:在多线程中,可能有多个线程试图访问一个有限的资源,必须预防这种情况的发生.所以引入了同步机制:在线程使用一个资源时为其加锁,这样其他的线程便不能访问那个资源了,直 ...
- 马士兵 java 学习笔记_马士兵java教程笔记1
---恢复内容开始--- 前记 虽然已经是个研究生了,但是会的东西还是特别的少 甚至连java都不能说是很会 所以准备从现在开始能好好的学习java 变成java master 标识符 标识符是由字母 ...
- 中级java面试题_最新中级Java面试题及答案
1.Java的HashMap是如何工作的? HashMap是一个针对数据结构的键值,每个键都会有相应的值,关键是识别这样的值. HashMap基于hashing原理,我们通过put()和get()方法 ...
最新文章
- 疑问:c++中的memset
- Android -------GestureDetector类的用法
- modsecurity配置指令学习
- 「神策智能推荐」如何助力企业?惠头条、纵横文学、东方明珠、妈妈帮等这样说...
- ACM PKU1703 Find them, Catch them
- 凸包模板(Graham算法)
- 从外卖员到程序员,自学3年终于转行成功,三面“拿下”拼多多,把经历分享给你们!
- 计算机教师职业幸福感,教师的职业幸福感是什么
- WLAN配置实例(二)——三层组网隧道转发
- 《达拉崩吧》扣哒世界版——在扣哒世界中学习编程
- t470换屏线_thinkpad t470怎么样?thinkpad t470拆机图解全面评测
- 华为 鸿蒙出处,华为商标名“鸿蒙”原来出自《山海经》,网友直呼:“太燃了”...
- Java软件工程师面试题汇总(持续更新)
- [hive 报错]:FAILED:SemanticException [Error 10025] Expression not in GROUP BY key
- Android应用开发性能优化完全分析
- 基于用户的API限流策略
- vue+图片裁剪vue-cropper以及api
- 在Anaconda3下安装tensorflow-gpu库的经验之谈
- c语言 数据结构 课程设计 通讯录制作
- 一阶广义差分模型_4.2 序列相关性_清华大学:计量经济学(李子奈博导)_ppt_大学课件预览_高等教育资讯网...