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 instance
Instantiating 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 中国是世界绿色发展的坚定行动派 7903965
- 2 中国这两个邻国又到战争边缘 7809477
- 3 “中国赢下了这一轮” 7712286
- 4 航天员乘组拍下“太空全家福” 7618423
- 5 不要欺负七旬老人唐国强 7524499
- 6 猝死的猿辅导员工:童年丧父考上名校 7428238
- 7 妥协换不来尊重 日本又给打了个样 7329495
- 8 儿子悄悄考上北大妈妈惊成静止画面 7231952
- 9 Create2025百度AI开发者大会 7135601
- 10 韩国残运会盒饭只有泡菜小菜引众怒 7048824