1、恶汉模式:直接创建对象,不存在线程安全问题
/** * 恶汉模式:在类初始化时直接创建实例对象,不管你是否需要,都会创建这个对象 * * (1)构造器私有化 * (2)自行创建,并且用静态变量保存 * (3)向外提供这个实例 * (4)强调这是一个单利,所以我们用final修饰 */ public class SingleTon { public final static SingleTon INSTANCE = new SingleTon(); private SingleTon(){ } }
/** * 枚举类型:表示该类型的对象是有限的几个 * 我们可以限定为一个,就成了单利 */ public enum SingleTon2 { INSTENCE }
应用实例:有可能需要加载某个文件中的信息
public class SingleTon3 { public final static SingleTon3 INSTANCE; private String info; static { try { Properties properties = new Properties(); properties.load(SingleTon3.class.getClassLoader().getResourceAsStream("singel.properties")); INSTANCE = new SingleTon3(properties.getProperty("info")); } catch (IOException e) { throw new RuntimeException(e); } } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } private SingleTon3(String info) { this.info = info; } @Override public String toString() { return "SingleTon3{" + "info=‘" + info + ‘\‘‘ + ‘}‘; } }
2、懒汉模式:延迟创建对象
1、存在线程安全问题
** * 懒汉模式:延迟创建实例对象 * * (1)构造器私有化 * (2)用一个静态变量保存这个唯一实例 * (3)提供一个静态方法,获取这个实例对象 * */ public class SingleTon4 { private static SingleTon4 instance; private SingleTon4(){ } public static SingleTon4 getInstance(){ if (instance == null){ try { Thread.sleep(100); }catch (InterruptedException e){ e.printStackTrace(); } instance = new SingleTon4(); } return instance; } }
public class TestSingleTon4 { public static void main(String[] args) throws Exception{ /*SingleTon4 s4 = SingleTon4.getInstance(); SingleTon4 s44 = SingleTon4.getInstance(); System.out.println(s4 == s44);*/ //存在线程安全问题 Callable<SingleTon4> c = new Callable<SingleTon4>() { @Override public SingleTon4 call() throws Exception { return SingleTon4.getInstance(); } }; ExecutorService es = Executors.newFixedThreadPool(2); Future<SingleTon4> f1 = es.submit(c); Future<SingleTon4> f2 = es.submit(c); SingleTon4 s1 = f1.get(); SingleTon4 s2 = f2.get(); System.out.println(s1 == s2); System.out.println(s1); System.out.println(s2);; } }
结果
false com.lk.SingleTon4@6d6f6e28 com.lk.SingleTon4@135fbaa4
解决线程不安全
public class SingleTon5 { private static SingleTon5 instance; private SingleTon5() { } public static SingleTon5 getInstance() { if (instance == null) { synchronized (SingleTon5.class) { if (instance == null) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } instance = new SingleTon5(); } } } return instance; } }
2、静态内部类实现(线程安全)
** * 在内部类加载和初始化时,才创建INSTANCE实例对象 * 静态内部类不会自动随着外部的加载和初始化而初始化,他要单独加载和初始化 * 因为是在内部类加载和初始化,创建的,是线程安全的 */ public class SingleTon6 { private SingleTon6(){ } private static class inner{ private static final SingleTon6 INSTANCE = new SingleTon6(); } public static SingleTon6 getInstance(){ return inner.INSTANCE; } }
原文:https://www.cnblogs.com/karrya/p/11286046.html