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 和人民在一起 7983956
- 2 柯洁被判负 7977464
- 3 警惕!今年第一场大寒潮或波及全国 7814522
- 4 今天明天 都是小年 7751016
- 5 王菲时隔7年再上春晚 将唱这首歌 7606028
- 6 女子称因未婚生育被取消村集体分红 7539733
- 7 公务员省考:学历要求越来越高 7418161
- 8 59岁陈慧娴演唱会上出意外 7335168
- 9 尹锡悦穿10号囚服 狱警叫他10号 7252663
- 10 造谣“董明珠停职” 5人被行政处罚 7132060