1.饿汉模式(立即加载模式)与多线程
不管需不需要用到实例都要去创建实例,即在类产生的时候就创建好实例
package com.thread; /** * 饿汉模式 * * @author yyx 2018年12月28日 */ public class EhanSingleton { public EhanSingleton() { } private static EhanSingleton ehanSingleton = new EhanSingleton(); public static EhanSingleton getInstance() { try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return ehanSingleton; } }
package com.thread; public class MyThread extends Thread { public static void main(String[] args) { MyThread m1 = new MyThread(); MyThread m12 = new MyThread(); MyThread m13 = new MyThread(); m1.start(); m12.start(); m13.start(); } @Override public void run() { System.out.println(EhanSingleton.getInstance().hashCode()); } }
运行结果的一种:
507247953
507247953
507247953
在多线程下,算出来的结果每个对象的 hashcode的值是一样的,是线程安全的
2.懒汉模式(延迟加载模式)与多线程
需要用到创建实例了程序再去创建实例,不需要创建实例程序就“懒得”去创建实例
package com.thread; /** * 懒汉模式 * * @author yyx 2018年12月28日 */ public class LhanSingleton { public LhanSingleton() { } private static LhanSingleton lhanSingleton; public static LhanSingleton getInstance() { if (lhanSingleton == null) { try { Thread.sleep(3000); lhanSingleton = new LhanSingleton(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return lhanSingleton; } }
package com.thread; public class MyThread extends Thread { public static void main(String[] args) { MyThread m1 = new MyThread(); MyThread m12 = new MyThread(); MyThread m13 = new MyThread(); m1.start(); m12.start(); m13.start(); } @Override public void run() { System.out.println(LhanSingleton.getInstance().hashCode()); } }
运行结果的一种:
1486308634
1560533534
507247953
懒汉模式在单线程中是符合单例模式的,不过在多线程环境中是不符合单例模式
3.懒汉模式线程安全的解决机制
3.1 同步代码块
package com.thread; /** * 懒汉模式 * * @author yyx 2018年12月28日 */ public class LhanSingleton { public LhanSingleton() { } private static LhanSingleton lhanSingleton; public static LhanSingleton getInstance() { synchronized (LhanSingleton.class) { if (lhanSingleton == null) { try { Thread.sleep(3000); lhanSingleton = new LhanSingleton(); } catch (InterruptedException e) { e.printStackTrace(); } } } return lhanSingleton; } }
3.2 同步方法
package com.thread; /** * 懒汉模式,不推荐 * * @author yyx 2018年12月28日 */ public class LhanSingleton { public LhanSingleton() { } private static LhanSingleton lhanSingleton; public static synchronized LhanSingleton getInstance() { if (lhanSingleton == null) { try { Thread.sleep(3000); lhanSingleton = new LhanSingleton(); } catch (InterruptedException e) { e.printStackTrace(); } } return lhanSingleton; } }