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 跟着总书记打卡博物馆 4930329
- 2 以色列总理涉嫌战争罪被申请逮捕令 4917171
- 3 伊朗总统坠机细节:空难后几分钟离世 4861068
- 4 如何充分激发各类经营主体活力 4705335
- 5 外交部:台湾是中国一省 没独立地位 4605755
- 6 吴艳妮登上英国报纸:被赞迷人 4527321
- 7 汪峰新女友曾参加《非诚勿扰》 4413805
- 8 520垃圾桶变花桶 4322204
- 9 新疆辟谣楼兰故城门票3500元 4285194
- 10 微信转账520和1314能要回吗 4149348