1、懒汉式 不足:在多线程环境中存在多个对象 ,线程不安全
public class Singleton {
private static Singleton singleton;
private Singleton(){
}
public static Singleton getInstance(){
if (singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
2、饿汉式 单例模式,线程安全 不足:类加载时创建对象,该类不管是否使用都存在一个对象 ,创建对象没法传递参数
public class HungrySingleton {
private static HungrySingleton instace;
/*
* 静态代码块在类加载期间初始化,只被执行一次
* */
static {
try {
instace = new HungrySingleton();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* 防止反射创对象
* */
private HungrySingleton() throws Exception {
if(instace!=null){
throw new Exception("该类只能有一个实例");
}
}
public static HungrySingleton getInstance(){
return instace;
}
}
3、静态内部类,单例模式。线程安全,解决懒汉式中无论如可都存在一个对象问题
public class StaticInnerSingleton {
private StaticInnerSingleton(){
}
public static StaticInnerSingleton getInstance(){
return InnerClass.instance;
}
/*
* 静态内部类
* */
private static class InnerClass{
private static final StaticInnerSingleton instance = new StaticInnerSingleton();
}
}
4、双层校验,单例模式,线程安全 不足:在第一次创建对象时候需要同步
public class DclSingleton {
private volatile static DclSingleton instancce;
private DclSingleton(){
}
public static DclSingleton getInstance(){
if (instancce==null){
synchronized (DclSingleton.class) {
if (instancce == null) {
instancce = new DclSingleton();
}
}
}
return instancce;
}
}
写一个Test类对其进行测试
public class Test {
public static void main(String[] args) throws Exception {
/* Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance==instance1);
*/
/*懒汉式
for (int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0;j<10;j++){
System.out.println(Singleton.getInstance());
}
}
}).start();
}*/
/* for (int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0;j<10;j++){
System.out.println(Singleton.getInstance());
}
}
}).start();
}*/
/* HungrySingleton instance = HungrySingleton.getInstance();
Class<HungrySingleton> cls = HungrySingleton.class;
//获取类中的所有构造方法
Constructor<HungrySingleton> constructor = cls.getDeclaredConstructor();
// Constructor<HungrySingleton> constructor = cls.getConstructor();
//设置私有构造方法可访问
constructor.setAccessible(true);
//使用反射实例化对象
HungrySingleton instannce2 = constructor.newInstance();
System.out.println(instance==instannce2);*/
for (int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0;j<10;j++){
System.out.println(EnumSingleton.INSTANCE);
}
}
}).start();
}
}
}