方法一:
public class Singleton1 {
private static Singleton1 singleton = new Singleton1();
private Singleton1() {
}
public static Singleton1 getSin() {
return singleton;
}
}
- 这种方式的缺点是在类加载的时候就会直接new出一个对象出来,当系统中这样的类比较多时,会很慢。
- 现在流行的设计都是延迟加载,在第一次使用的时候才初始化第一个对象
方法二:
public class Singleton2 {
private static Singleton2 instance;
private Singleton2() {
}
public static synchronized Singleton2 getSin() {
if(instance == null)
instance = new Singleton2();
return instance;
}
}
- 这种方式一次锁住了一个方法,粒度有些大,改进就是只锁住其中的new语句就可以了,这便是所谓的双重锁机制
方法三:
public class Singleton3 {
private static Singleton3 instance;
private Singleton3() {
}
public static Singleton3 getSin() {
if(instance == null) {
synchronized (Singleton3.class) {
if(instance == null)
instance = new Singleton3();
}
}
return instance;
}
}
方法四:
- 这种情况既不用加锁,也不用实现懒加载
- 懒加载:当我们需要的时候才会new出来
import java.util.ArrayList;
import java.util.Arrays;
public class Singleton {
private Singleton() {
System.out.println("single");
}
private static class Inner{
private static Singleton singleton = new Singleton();
}
private static Singleton getSingleton() {
return Inner.singleton;
}
// 无论多少个线程访问的时候,拿到的都是同样的一个对象
public static void main(String[] args) {
Thread[] ths = new Thread[200];
for(int i = 0; i < ths.length; i++) {
ths[i] = new Thread(() -> {
Singleton.getSingleton();
});
}
Arrays.asList(ths).forEach(o -> o.start());
}
}