java常用设计模式一:单例模式
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