Java中的懒惰实例化与急切实例化:哪个更好?



public static HeroesDB heroesDB; // #A
private SingletonNaiveApproach() {} // #B
public HeroesDB getHeroesDB() { // #C
if (heroesDB == null) { // #D
heroesDB = new HeroesDB(); // #E
}
return heroesDB; // #F
}
static class HeroesDB { }
}开始(#A),声明一个静态内部类HeroesDB。将变量声明为静态的变量,它可以在应用程序中共享。 下一步(#B),创建一个私有构造函数,以避免从类外部直接实例化。因此,必须使用getHeroes()方法来获取一个实例。 在下一行(#C),看到了有效地从HeroesDB返回实例的方法。 接下来(#D),检查heroesDB实例是否为空。如果是空,将创建一个新实例。否则什么也不做。 最后(#F),返回heroesDB对象实例。

public class SingletonSynchronizedApproach {
public static HeroesDB heroesDB;
private SingletonSynchronizedApproach() {}
public synchronized HeroesDB getHeroesDB() {
if (heroesDB == null) {
heroesDB = new HeroesDB();
}
return heroesDB;
}
static class HeroesDB { }
}
public class ThreadSafeSynchronized {
public static volatile HeroesDB heroesDB;
public static HeroesDB getHeroesDB() {
if(heroesDB == null) {
synchronized (ThreadSafeSynchronized.class) {
if(heroesDB == null) {
heroesDB = new HeroesDB();
}
}
}
return heroesDB;
}
static class HeroesDB { }
}

public class HeroesDatabaseSimpleEager {
public static final HeroesDB heroesDB = new HeroesDB();
static HeroesDB getHeroesDB() {
return heroesDB;
}
static class HeroesDB {
private HeroesDB() {
System.out.println("Instantiating heroesDB eagerly...");
}
@Override
public String toString() {
return "HeroesDB instance";
}
}
public static void main(String[] args) {
System.out.println(HeroesDatabaseSimpleEager.getHeroesDB());
}
}
The output from this code would be:
Instantiating heroesDB eagerly...
HeroesDB instanceInstantiating heroesDB eagerly...
HeroesDB instance
public enum HeroesDatabaseEnum {
INSTANCE;
int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public static void main(String[] args) {
System.out.println(HeroesDatabaseEnum.INSTANCE);
}Creating instance...
INSTANCE
需要同步才能在多线程环境中工作。 由于if检查和同步,性能会变慢。 当需要该对象时,应用程序可能会有明显的懒惰。
在大多数情况下,对象将在应用程序启动时被实例化。 使用对象时没有延迟,因为它已经被实例化了。 它在多线程环境中工作良好。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class LazyHomerBeerCreationChallenge {
public static int i = 0;
public static Beer beer;
static void createBeer() {
if (beer == null) {
try {
Thread.sleep(200);
beer = new Beer();
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(LazyHomerChallenge::createBeer);
executor.submit(LazyHomerChallenge::createBeer);
executor.awaitTermination(2, TimeUnit.SECONDS);
executor.shutdown();
System.out.println(i);
}
public static class Beer {}
}

懒惰实例化需要在实例化之前进行是否为空的检查。 在多线程环境中同步对象以实现懒惰实例化。 急切实例化不需要对对象进行是否为空的检查。 使用枚举是一种有效且简单的紧急实例化方法。
原文链接:
https://www.infoworld.com/article/3675954/lazy-vs-eager-instantiation-in-java-which-is-better.htm

关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
赞助链接
排名
热点
搜索指数
- 1 向着宏伟目标接续奋进 7904460
- 2 多地涨工资落地 涨幅在10%以上 7808499
- 3 解放军演练抢滩登陆 机器狗打头阵 7712288
- 4 未来五年房市、收入、消费这样干 7619380
- 5 43名新生弃读东华大学不必公告姓名 7521195
- 6 3个女孩2个月将房子住“包浆”跑路 7425700
- 7 净网:查处虚构“女技术黑客”案 7331931
- 8 1小时2架美军机坠南海 更多信息披露 7236478
- 9 湖北省委原书记蒋超良被双开 7135543
- 10 按摩店初中文凭小伙娶美国女博士 7040591







51CTO技术栈
