1、饿汉式
package singleton.demo;/*** @author Administrator* @date 2019/01/07*/ public class Singleton {//在调用getInstance方法前,实例已经创建好private static Singleton instance = new Singleton();//私有构造,防止被实例化private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;} }
2、懒汉式
package singleton.demo;/*** @author Administrator* @date 2019/01/07*/ public class Singleton {//初始设置为null,需要时才被加载,延迟加载private static Singleton instance = null;//私有构造,防止被实例化private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;} }
以上两种模式:只适合在单线程环境使用,多线程环境容易出现不同步的情况。在多线程模式下,可能产生问题。比如下面的实例
package singleton.demo;/*** @author Administrator* @date 2019/01/07*/ public class Singleton {//初始设置为null,需要时才被加载,延迟加载private static Singleton instance = null;//私有构造,防止被实例化private Singleton() {}public static Singleton getInstance() {if (instance == null) {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}instance = new Singleton();}return instance;} }
package singleton.demo;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** @author Administrator* @date 2019/01/07*/ public class Test {public static void main(String[] args){ExecutorService executorService = Executors.newCachedThreadPool();for(int i=0;i<5;i++){executorService.submit(new Runnable() {public void run() {System.out.println(Singleton.getInstance().hashCode());}});}executorService.shutdown();} }
执行结果:
1369340138 1555013046 285003072 270952636 84064941
之所以出现不同步,是因为,当多个线程执行 getInstance() 的时候,都发现instance是null,所以每个线程各自创建了一个instance
3、使用static块实现线程安全的单例模式
注意:以下try-catch不是模式需要的代码,这里只是为了测试多线程环境才加上的
package singleton.demo;/*** @author Administrator* @date 2019/01/07*/ public class Singleton {//初始设置为null,需要时才被加载,延迟加载private static Singleton instance = null;//私有构造,防止被实例化private Singleton() {}static {instance = new Singleton();}public static Singleton getInstance() {if (instance == null) {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}instance = new Singleton();}return instance;} }
package singleton.demo;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** @author Administrator* @date 2019/01/07*/ public class Test {public static void main(String[] args){ExecutorService executorService = Executors.newCachedThreadPool();for(int i=0;i<5;i++){executorService.submit(new Runnable() {public void run() {System.out.println(Singleton.getInstance().hashCode());}});}executorService.shutdown();} }
2050945573 2050945573 2050945573 2050945573 2050945573