Functional Programming in Java venkat(14) Being Lazy
admin
2024-03-03 00:46:02
0

文章目录

  • Functional Programming in Java venkat(14): Being Lazy
    • Delayed Initialization
      • A Familiar Approach
      • Providing Thread Safety
      • Adding a Level of Indirection
    • 英文

Functional Programming in Java venkat(14): Being Lazy

这里是记录学习这本书 Functional Programming in Java: Harnessing the Power Of Java 8 Lambda Expressions 的读书笔记,如有侵权,请联系删除。

本章的内容:延时创建heavyweight 的对象,然后把eager的计算的情形转变为lazy评估。

In this chapter we start with a task to postpone the creation of a heavyweight object, then we turn some eager computations into lazy evaluations.

Delayed Initialization

eager is easy to write and to reason about. But delaying commitments until the last responsible moment is a good agile practice.

A Familiar Approach

把heavyweight的资源放在Heavy类中。

move the heavyweight resources into another class—say, Heavy. Then an instance of Holder will keep a reference to an instance of Heavy and route calls to it as appropriate.

package fpij;public class Heavy {public Heavy() { System.out.println("Heavy created"); }public String toString() { return "quite heavy"; }
}

下面是最简单的延迟创建Heavy对象,当heavy = null 的时候创建新的Heavy对象,否则的话返回heavy对象。

package fpij;public class HolderNaive {private Heavy heavy;public HolderNaive() {System.out.println("Holder created");}public Heavy getHeavy() {if(heavy == null) {heavy = new Heavy();}return heavy;}//...public static void main(final String[] args) {final HolderNaive holder = new HolderNaive();System.out.println("deferring heavy creation...");System.out.println(holder.getHeavy());System.out.println(holder.getHeavy());}
}

但是存在问题:线程不安全

如果多个线程同时进来,可能会创建多个heavy对象。

That appears to work. The solution, however, is not simple; it is a familiar
but also a rather simplistic solution that fails thread safety. Let’s work through
it.

Providing Thread Safety

变成线程安全的需要synchronized关键字

  public synchronized Heavy getHeavy() {if(heavy == null) {heavy = new Heavy();}return heavy;}

多个线程进来,满足互斥。只有一个可以进入创建对象,其他的线程进入之后会发现对象已经被之前的线程创建,从而直接返回heavy对象。

If two or more threads call this method concurrently, due to mutual exclusion only one will be allowed to enter and the others will queue up for their turn. The first one to enter into the method will create the instance. When subsequent threads enter this method they will see that the instance already exists,
and will simply return it.

我们避免了竞赛条件,但这个解决方案产生了另一个负面影响。现在对getHeavy()方法的每一次调用都必须忍受同步开销;即使没有同时竞争的线程,调用线程也必须跨越内存障碍(memory barrier)。

We averted the race condition, but the solution created another negative impact. Every call to the getHeavy() method now has to endure the synchronization overhead; the calling threads have to cross the memory barrier even if there are no concurrently competing threads.

Adding a Level of Indirection


import java.util.function.Supplier;public class Holder {private Supplier heavy = () -> createAndCacheHeavy();public Holder() {System.out.println("Holder created");}public Heavy getHeavy() {return heavy.get();}//...
}

当Holder的实例被创建时,我们可以看到,Heavy的实例并没有被创建。这种设计实现了懒惰初始化的目标。我们还需要一个非苛刻的线程安全解决方案。这就是createAndCacheHeavy()方法的用处。

When an instance of Holder is created, as we can see, an instance of Heavy is not created. This design achieves the goal of lazy initialization. We also need a non-draconian solution to thread safety. This is where the createAndCacheHeavy() method comes in.

查看createAndCacheHeavy方法

 private synchronized Heavy createAndCacheHeavy() {class HeavyFactory implements Supplier {private final Heavy heavyInstance = new Heavy();public Heavy get() { return heavyInstance; }}if(!HeavyFactory.class.isInstance(heavy)) {heavy = new HeavyFactory();}return heavy.get();}

让我们考虑这样一个场景:一个新的Holder实例刚刚被创建。我们假设有两个线程同时调用getHeavy()方法,随后第三个线程在很久之后调用这个方法。当前两个线程在Holder中调用默认Supplier的get()方法时,createAndCacheHeavy()方法会让其中一个线程通过,让另一个线程等待。第一个进入的线程将检查heavy是否是HeavyFactory的一个实例。由于它不是默认的Supplier,这个线程将用HeavyFactory的一个实例来替换heavy。最后它返回这个HeavyFactory所持有的Heavy实例。

Let’s consider a scenario in which a new instance of Holder has just been created. Let’s assume two threads invoke the getHeavy() method concurrently, followed by a third thread calling this method much later. When the first two threads call the default supplier’s get() method in the Holder, the createAndCacheHeavy() method will let one of them through and make the other wait. The first thread to enter will check if heavy is an instance of the HeavyFactory. Since it is not the default Supplier, this thread will replace heavy with an instance of HeavyFactory. Finally it returns the Heavy instance that this HeavyFactory holds.

现在heavy已经被HeavyFactory所取代,随后对getHeavy()方法的调用将直接进入HeavyFactory的get()方法,不会产生任何同步开销。

Now that heavy has been replaced with HeavyFactory, subsequent calls to the getHeavy() method will go directly to the HeavyFactory’s get() method and will not incur any synchronization overhead

我们设计了懒惰的初始化,同时,避免了空值检查。此外,我们确保了懒惰实例创建的线程安全。这是虚拟代理模式的一个简单、轻量级的实现。接下来我们将使用lambda表达式来延缓函数的评估。

We designed lazy initialization and, at the same time, avoided null checks. Furthermore, we ensured the thread safety of the lazy instance creation. This is a simple, lightweight implementation of the virtual proxy pattern. Next we’ll use lambda expressions to postpone function evaluations.

英文

overhead: 开销

will not incur any synchronization overhead(不会产生任何同步开销)

相关内容

热门资讯

瑞丰银行招标结果:瑞丰银行LE... 证券之星消息,根据天眼查APP-财产线索数据整理,浙江绍兴瑞丰农村商业银行股份有限公司7月6日发布《...
“四个共享”助力百色芒果行销大... 7月9日,为期两天的“芒香入湾·合作共赢”百色芒果广东产销对接暨展销推介活动在广东区域协作消费帮扶产...
这个拥有百年历史的设备,正成为... 文|财联社 电力从发电端输送至用户端的全过程,约90%的电力都会流经变压器:输电环节升压以减少输电...
华泰证券执委陈天翔:AI进入财... 财联社7月10日讯(记者 赵昕睿)由财联社携手华夏基金、腾势共同举办的第五届财富管理论坛暨第三届“财...
第四届暑期港澳青创嘉年华缤纷日... 中新网广州7月9日电 (张璐 余冰冰)“创响湾区·就约盛夏”第四届暑期港澳青创嘉年华缤纷日活动暨大湾...
美元通胀变化如何影响黄金? 在金融市场中,美元通胀的变化对黄金价格有着显著的影响。要理解这种影响,我们首先需要明白美元通胀的本质...
原创 永... 2026年以来,永诚财产保险股份有限公司(下称永诚财险)合规风险持续暴露。这家由华能集团联合五大电力...
“为哈梅内伊复仇”,伊朗打击美... 伊朗南部布什尔市和乔加达克市9日晚传出爆炸声。当地居民表示,在伊朗南部的阿巴斯港也听到了数声爆炸。伊...
巴西将12%原油出口税延长60... △巴西首都巴西利亚(资料图) 巴西发展、工业、贸易和服务部9日发布会议决议显示,巴西对外贸易商会执行...
茅台健康产业公司挂牌转让10%... 茅台集团旗下一家公司部分股权被挂牌转让。 7月9日,南都湾财社-酒水新消费指数课题组记者从北京产权交...
深度 | FOF“赛马” 当数十万亿元到期存款寻找新出路时,一个曾蛰伏于公募版图角落的小众品类——FOF(基金中基金)正迎来一...
锚定价值创造 深耕全链协同 蒙... 7月9日,由中国奶业协会主办的第十七届奶业大会 奶业20强(D20)论坛暨2026奶业展览会在江西省...
原创 母... 创始人离世1年后爆发家族纷争。 作者 | 贾紫聪 编辑丨高岩 来源 | 野马财经 A股的资本江湖里...
AI制药的尽头,还得是CXO 2012年,当AlexNet在ImageNet竞赛中横空出世、将图像识别错误率一举降低近一半时,制药...
假如长鑫上市,冲上1万亿美金! 来源:市场资讯 来源:格隆 本文作者 | 弗雷迪 数据支持 | 勾股大数据 01 1995年一月,《...
SK海力士美国上市带动杠杆ET... 7月10日,财闻海外资讯消息,ProShares、Leverage Shares和Rex Share...
真金白银出手!近30家基金公司... 近期市场震荡之际,公募基金自购再度升温。 根据Wind公开数据统计,截至7月初,最近一个月已有近30...
人大讲座风波后,张小龙辞任CE... 本报(chinatimes.net.cn)记者于玉金 北京报道 人大讲座风波后,粉笔CEO张小龙离职...
Meta收涨4.7%背后:扎克... 格隆汇7月10日|Meta周四低开高走,最终收涨4.7%,报631.48美元。 据金融投资AI助手...