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 { }
}
左右滑动查看完整代码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
注意,在本例中没有进行是为空的检查。当HeroesDB被声明为HeroesDatabaseSimpleEager中的实例变量时,它就被实例化了。因此,每次访问HeroesDatabaseSimpleEager类时,都会从HeroesDB获得一个实例。还重写了toString()方法,以简化HeroesDB实例的输出。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
这段代码是线程安全的。它保证只创建一个实例,并且序列化对象,这意味着可以更容易地传输它。另一个细节是,对于枚举有一个隐式的私有构造函数,这保证了不会不必要地创建多个实例。枚举被认为是使用急切实例化的最佳方法之一,因为它简单而有效。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