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(不会产生任何同步开销)

相关内容

热门资讯

跨境电商巨无霸,赴港IPO获证... 来源:上海证券报 7月10日,中国证监会国际合作司发布关于SHEIN Global Holdings...
陪爸妈走过的第四个城市 陪爸妈走过的第四个城市 开篇 今年春天,趁着天气刚刚好,我又带着爸妈出了趟门。算上这次,是陪他们走...
百度沈抖:未来 90% 工作都... “未来90%的工作,都可能有智能体深度参与、协助完成。”在百度AIDAY百度搭子专场上,百度集团执行...
港股风向标|恒指短线放量滞涨 ... 财联社7月10日讯(编辑 冯轶)今日港股再度冲高回落,三大指数午后集体走弱。截至收盘,恒生指数、国企...
MLCC周期全面爆发!风华高科... 7月10日,国内被动元件龙头风华高科(000636.SZ)披露2026年半年度业绩预告,上半年净利润...
关停杠杆炒金!银行个人贵金属代... 今年6月以来,交通银行、招商银行、工商银行、建设银行等多家银行相继发布公告,宣布将于7月下旬起停办代...
原创 许... 许家印当年为何跟黄有龙搞在一起?背后到底有何猫腻?许家印跟黄有龙堪称是中国资本市场的两大奇人。一个凭...
世界杯第29日前瞻:西班牙vs... 北京时间7月11日凌晨3点,2026年美加墨世界杯进入第29个比赛日的争夺,将展开第二场1/4决赛争...
食品饮料周报:白酒去库存加速,... 证券之星食品饮料行业周报:2026年7月6日-2026年7月10日,沪深300指数下跌1.27%,申...
沈阳闲置黄金变现爆发,宏昇贵金... 近期,国际黄金价格持续震荡上行,沈阳地区贵金属回收市场迎来交易热潮。随着居民家庭闲置黄金存量的释放,...
Claude Code “高危... 出品 | 妙投APP 作者 | 张贝贝 编辑 | 丁萍 头图 | AI生图 7月8日,一则关于Cla...
新豪轩门窗X新华网《极致中国造... 从“中国制造”的规模优势迈向“中国创造”的价值跃升,中国品牌正以持续创新重塑全球竞争力。在这一进程中...
上市械企董事长,被女儿、女婿联... 来源:医疗器械经销商联盟 7月8日,科创板上市公司奥精医疗突发重磅公告,瞬间引爆资本市场与舆论圈。公...
汕头市优佳适科技有限公司成立 ... 天眼查App显示,近日,汕头市优佳适科技有限公司成立,注册资本50万人民币,经营范围为一般项目:技术...
砍掉两百个BU与近千家代持外壳... 在智能清洁硬件赛道凭借激进出海与疯狂营销一路狂飙的追觅(Dreame),突然在资本市场的前夜迎来了最...
原创 昨... 美东时间 7 月 9 日夜,纽约债市收盘钟声敲响时,交易大厅里紧绷了一周的情绪终于松了下来。本周总额...
段永平再次增持泡泡玛特 持股比... 观点网讯:7月10日,据港交所披露,知名投资人段永平再度增持泡泡玛特股票。 此次增持后,段永平持股数...
包揽全球80%的产能,又一个行... 作者: 快刀财经 郑栾 近日,新消费行业又迎来一笔久违的大额融资——咖爷科技宣布完成B轮融资,由美...
外储增配香港资产,可能会买啥? 界面新闻记者 | 杨志锦 界面新闻编辑 | 王姝 本周,央行行长潘功胜在香港的讲话引起市场广泛关...
最贵一套1.5亿,上海徐汇两大... 界面新闻记者 | 王婷婷 上海顶豪市场年度大戏来了。 7月11日,上海西岸美高梅酒店将迎来两大豪宅...