懒惰评估

最近,我正在编写log4j附加程序,并希望在自定义附加程序创建过程中使用logger记录一些诊断详细信息,但是log4j初始化仅在创建附加程序实例后才完成,因此该阶段记录的消息将被忽略。

我感到需要在自定义附加程序中进行延迟初始化,并开始研究选项。 在此博客中,我将分享我尝试过的事情。

我想到的一件事是Singleton方法,但是现在已知的事实是Singleton会导致测试问题,并且无法扩展它,因此混合并发和对象构造的方法并不是那么好。

如果需要单例,那么最好使用依赖注入框架而不是破坏应用程序代码。 让我们回到延迟初始化/评估。

一些编程语言(例如scala / swift等)支持惰性,因此不需要自定义代码即可执行此操作,但是在Java空间中,我们仍然必须编写线程安全的代码才能正确执行。

让我们看一下Java中的一些选项以及获得的性能类型。

–使用同步的蛮力

这是最简单,效率最低的一种,scala正在使用这种方法。 Scala一个可用@ ScalaLazy.java

public class SingleLock<V> implements Lazy<V> {private Callable<V> codeBlock;private V value;public SingleLock(Callable<V> codeBlock) {this.codeBlock = codeBlock;}@Overridepublic synchronized V get() {if (value == null) {setValue();}return value;}private void setValue() {try {value = codeBlock.call();} catch (Exception e) {throw new RuntimeException(e);}}}

–双锁

编写起来并不复杂,并且具有良好的性能。

public class DoubleLock<V> implements Lazy<V> {private Callable<V> codeBlock;private V value;private volatile boolean loaded;public DoubleLock(Callable<V> codeBlock) {this.codeBlock = codeBlock;}@Overridepublic V get() {if (!loaded) {synchronized (this) {if (!loaded) {setValue();loaded = true;}}}return value;}private void setValue() {try {value = codeBlock.call();} catch (Exception e) {throw new RuntimeException(e);}}}

–使用未来任务

这种方法易于编写,并具有良好的性能。

public class LazyFutureTask<V> implements Lazy<V> {private final FutureTask<V> futureTask;public LazyFutureTask(Callable<V> codeBlock) {this.futureTask = new FutureTask<>(codeBlock);}@Overridepublic V get() {futureTask.run();return getValue();}private V getValue() {try {return futureTask.get();} catch (Exception e) {throw new RuntimeException(e);}}
}

双锁方法可提供最佳性能,而蛮力则是最差的。 我使用不同数量的线程对100万次调用进行了快速基准测试。

三个都
单锁性能非常差,让我们通过删除单锁来查看数字,以了解“双锁和未来任务”的执行情况。

2种

这些基准测试很快完成,但是详细的基准测试数字应该接近。

可以在github上获得此博客文章的代码

翻译自: https://www.javacodegeeks.com/2016/08/lazy-evaluation.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/351728.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python基础_格式化输出(%用法和format用法)

%用法 1、整数的输出 %o —— oct 八进制%d —— dec 十进制%x —— hex 十六进制 >>> print(%o % 20) 24 >>> print(%d % 20) 20 >>> print(%x % 20) 14 2、浮点数输出 2.1 格式化输出 %f ——保留小数点后面六位有效数字  %.3f&#xff0c;保留…

CSV大文件的处理(以ngsim数据为例):分割、导入与合并

逗号分隔值&#xff08;Comma-Separated Values&#xff0c;CSV&#xff0c;有时也称为字符分隔值&#xff0c;因为分隔字符也可以不是逗号&#xff09;&#xff0c;其文件以纯文本形式存储表格数据&#xff08;数字和文本&#xff09;。纯文本意味着该文件是一个字符序列&…

python用scrapy爬虫豆瓣_爬虫教程——用Scrapy爬取豆瓣TOP250

最好的学习方式就是输入之后再输出&#xff0c;分享一个自己学习scrapy框架的小案例&#xff0c;方便快速的掌握使用scrapy的基本方法。本想从零开始写一个用Scrapy爬取教程&#xff0c;但是官方已经有了样例&#xff0c;所以还是不写了&#xff0c;尽量分享在网上不太容易找到…

context-param与init-param的区别与作用

<context-param>的作用:web.xml的配置中<context-param>配置作用1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener> 和 <context-param></context-param>2.紧接着,容器创建一个Servl…

如何快速批量修改文件名

文件太多&#xff0c;文件名太乱&#xff0c;希望快速批量修改文件名&#xff0c;以下的两种方法可以帮到你&#xff0c;亲测好用。 方法一 1.选中需要批量修改的文件&#xff0c;如图1 图12.按F2键&#xff0c;输入文件名。如图2. 图23.Enter&#xff0c;效果如图3. 图3方法…

【LUOGU???】WD与积木 NTT

题目大意 把 \(n\) 个有标号物品分到一些有标号的箱子中且不允许为空&#xff0c;问期望箱子的数量。 多组询问。 \(n\leq 100000\) 题解 记 \(f_i\) 为 \(i\) 个有标号物品分到一些有标号的箱子中且不允许为空的箱子的数量之和。 记 \(g_i\) 为 \(i\) 个有标号物品分到一些有标…

7对讲机调频软件_对讲机怎么配对?

有好多朋友买到了新对讲机和老对讲机的频率不一样&#xff0c;从而导致了新旧对讲机无法通联。买到了新对讲机&#xff0c;我们要先知道旧对讲机的频率是多少。要想知道旧对讲机的频率是多少&#xff0c;我们就要需要一定的工具&#xff0c;首先我们要有一台XP系统的电脑&#…

RTK、IMU、RT3000

GPS/RTK 全球卫星定位系统(GPS)的全面建成和发展&#xff0c;导致了导航和测绘行业的一场重大深刻的技术革命。常规的静态GPS测量方法越来越多地应用于高精度控制网的建立&#xff0c;但利用该方法无法在野外对观测数据进行实时检核&#xff0c;从而造成观测结果不合格而需要返…

POJ--3974 Palindrome(回文串,hash)

链接&#xff1a;点击这里 #include<iostream> #include<algorithm> #include<stdio.h> #include<cstring> using namespace std; #define maxn 1000005 #define LL long long #define ull unsigned long long const LL P 131; ull p[maxn10],f[maxn]…

Springboot 两种方式配置启动热部署(图文界面)

目录 前言1. 类加载启动2. devtools前言 Java的热部署(Hot Deployment)是指在应用程序运行时更新或替换类文件,而无需重新启动整个应用程序。 代表不停止应用程序的情况下修改代码并立即看到变化,这对于开发和调试过程非常有用。 类加载器(Class Loader): Java应用程序…

Microsoft VBScript 编译器错误 错误原因 代码大全

Microsoft VBScript 编译器错误 错误 缺少语句ActiveServerPages,ASP0126(0x80004005)-->找不到包含文件 MicrosoftOLEDBProviderforODBCDrivers(0x80040E21)-->sql语句出错(数据类型不匹配或表名(字段名)错误或表处于编辑状态&#xff0c;或表不存在于conn打开的数据库…

hadoop3 禁用ec_Hadoop + Amazon EC2 –更新的教程

hadoop3 禁用ec在Hadoop的Wiki页面上放置了一个旧教程&#xff1a; http : //wiki.apache.org/hadoop/AmazonEC2 &#xff0c;但是最近我不得不遵循本教程&#xff0c;并且我注意到它没有涵盖某些Amazon新功能。 建议您已经熟悉Hadoop的基础来学习本教程&#xff0c;可以在Had…

libuv 原理_Libuv初理解

整体概念libuv是一个跨平台、专门写给nodejs的库&#xff0c;它的设计是围绕着事件驱动的异步I/O模型。在不同的I/O轮询机制上&#xff0c;libuv提供的不是简单抽象对象&#xff1a;handle和streams为sockets和其他实例提供了一个高级抽象。此外&#xff0c;libuv还提供了跨平台…

Matlab排序函数sort()和sortrows()

sort() 调用形式 1.Ysort(X) 对矩阵、向量或数组进行升序排列。 例1 >> amagic(4)a 16 2 3 135 11 10 89 7 6 124 14 15 1>> brand(1,4)b 0.8147 0.9058 0.1270 0.9134>> sort(a)ans 4 2 3…

[Swift]LeetCode968.监控二叉树 | Binary Tree Cameras

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号&#xff1a;山青咏芝&#xff08;shanqingyongzhi&#xff09;➤博客园地址&#xff1a;山青咏芝&#xff08;https://www.cnblogs.com/strengthen/&#xff09;➤GitHub地址&a…

Maven神秘化

由于我的Android开发的背景下&#xff0c;我比较习惯到摇篮 &#xff0c;而不是Maven的 。 尽管我知道Gradle基于Maven&#xff0c;但我从未调查过幕后发生的事情。 在过去的一周中&#xff0c;我一直在尝试了解细节并找出Maven的不同组成部分。 什么是Maven Maven是主要用于J…

走进JVM【二】理解JVM内存区域

引言 对于C程序员&#xff0c;内存分配与回收的处理一直是令人头疼的问题。Java由于自身的自动内存管理机制&#xff0c;使得管理内存变得非常轻松&#xff0c;不容易出现内存泄漏&#xff0c;溢出的问题。 不容易不代表不会出现问题&#xff0c;一旦内存泄漏或溢出的情况发生&…

mysql一对多_mysql一对多查询合并多的一方的数据。

有时候会有这样一个需求&#xff0c;查询的一条记录需要包含另一个表的多条记录&#xff0c;并且让多条记录成为一个字段组成最终的一条记录。比较难描述&#xff0c;看例子吧。创建一个产品表&#xff1a;create table product(proId int(10),proName varchar(50))创建一个成分…

Matlab矩阵、元胞数组的合并拼接

矩阵合并拼接 1.横向拼接 [a,b] [a b]均可 例1 >> amagic(3)a 8 1 63 5 74 9 2>> brand(3)b 0.6324 0.5469 0.15760.0975 0.9575 0.97060.2785 0.9649 0.9572>> c[a,b]c 8.0000 1.0000 6.0000 0.632…

Matlab拆分矩阵/Matlab如何分割大矩阵(mat2cell函数)

dim1Dist分割后矩阵行数组成的向量&#xff0c;dimNDist指的是分割后矩阵列数组成的向量 例有100*200的矩阵A >> Arand(100,200); >> bmat2cell(A,[30 40 30],[100 70 30])b 33 cell 数组{30100 double} {3070 double} {3030 double}{40100 double} {40…