温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java多线程实战之单例模式与多线程的实例详解

发布时间:2020-09-16 17:02:53 来源:脚本之家 阅读:155 作者:邋遢的流浪剑客 栏目:编程语言

1、立即加载/饿汉模式

 // 立即加载/饿汉模式 public class MyObject { private static final MyObject myObject = new MyObject(); private MyObject() { } public static MyObject getInstance() { return myObject; } }

立即加载/饿汉模式是在类创建的同时已经创建好一个静态的对象供系统使用,不存在线程安全问题

2、延迟加载/懒汉模式

 // 延迟加载/懒汉模式 public class MyObject { private static MyObject myObject; private MyObject() { } public static MyObject getInstance() { if (myObject == null) { myObject = new MyObject(); } return myObject; } }

延迟加载/懒汉模式是在调用方法时实例才被创建,在多线程环境下,会出现取出多个实例的情况,与单例模式的初衷是相背离的

1)、延迟加载/懒汉模式在多线程环境下创建出多个实例:

 // 延迟加载/懒汉模式 public class MyObject { private static MyObject myObject; private MyObject() { } public static MyObject getInstance() { try { if (myObject == null) { TimeUnit.SECONDS.sleep(3); myObject = new MyObject(); } } catch (InterruptedException e) { e.printStackTrace(); } return myObject; } }
 public class MyThread extends Thread { @Override public void run() { System.out.println(MyObject.getInstance().hashCode()); } }
 public class Run { public static void main(String[] args) { MyThread myThread = new MyThread(); MyThread myThread2 = new MyThread(); MyThread myThread3 = new MyThread(); myThread.start(); myThread2.start(); myThread3.start(); } }

运行结果:三次打印的hashCode不完全相等

2)、通过声明synchronized关键字解决线程安全问题:

 // 延迟加载/懒汉模式 public class MyObject { private static MyObject myObject; private MyObject() { } public static synchronized MyObject getInstance() { try { if (myObject == null) { TimeUnit.SECONDS.sleep(3); myObject = new MyObject(); } } catch (InterruptedException e) { e.printStackTrace(); } return myObject; } }

使用synchronized关键字,这种方法的运行效率很低,是同步运行的,下一个线程想要取得对象,则必须等上一个线程释放锁之后,才可以继续执行

3)、使用同步代码块解决线程安全问题:

 // 延迟加载/懒汉模式 public class MyObject { private static MyObject myObject; private MyObject() { } public static MyObject getInstance() { try { // 相当于public static synchronized MyObject getInstance() synchronized (MyObject.class) { if (myObject == null) { TimeUnit.SECONDS.sleep(3); myObject = new MyObject(); } } } catch (InterruptedException e) { e.printStackTrace(); } return myObject; } }

加入同步代码块,这种方法的运行效率也是非常低,和synchronized同步方法一样是同步运行的

4)、针对某些重要的代码进行单独的同步

 // 延迟加载/懒汉模式 public class MyObject { private static MyObject myObject; private MyObject() { } public static MyObject getInstance() { try { if (myObject == null) { TimeUnit.SECONDS.sleep(3); synchronized (MyObject.class) { myObject = new MyObject(); } } } catch (InterruptedException e) { e.printStackTrace(); } return myObject; } }

此方法只对实例化对象的关键代码进行同步,从语句的结构上来讲,运行的效率的确得到了提升。但如果是多线程的情况下还是无法解决得到同一个实例对象的结果

5)、使用DCL双检查锁机制

 // 延迟加载/懒汉模式 public class MyObject { private volatile static MyObject myObject; private MyObject() { } public static MyObject getInstance() { try { if (myObject == null) { TimeUnit.SECONDS.sleep(3); synchronized (MyObject.class) { if (myObject == null) { myObject = new MyObject(); } } } } catch (InterruptedException e) { e.printStackTrace(); } return myObject; } }

使用DCL双检查锁机制,既保证了不需要同步代码的异步执行性,又保证了单例的效果

3、使用静态内部类实现单例模式

 public class MyObject { private static class MyObjectHandler { private static MyObject myObject = new MyObject(); } private MyObject() { } public static MyObject getInstance() { return MyObjectHandler.myObject; } }

4、使用静态代码块实现单例模式

 public class MyObject { private static MyObject instance = null; private MyObject() { } static { instance = new MyObject(); } public static MyObject getInstance() { return instance; } }

5、使用enum枚举实现单例模式

 public class MyObject { public enum MyEnumSingleton { objectFactory; private MyObject myObject; private MyEnumSingleton() { myObject = new MyObject(); } public MyObject getInstance() { return myObject; } } public static MyObject getInstance() { return MyEnumSingleton.objectFactory.getInstance(); } }

枚举enum和静态代码块的特性相似,在使用枚举类时,构造方法会被自动调用,使用这个特性实现单例设计模式

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对亿速云的支持。如果你想了解更多相关内容请查看下面相关链接

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI