Java单例模式的写法
来源:互联网 发布:java导出pdf 编辑:程序博客网 时间:2024/04/29 05:48
第一种写法: 懒汉式单例
class Singleton{private static Singleton singleleton=null;pulic static Singleton getInstance(){if(singleleton==null){ singleleton=new Singleton() }return singleleton;}private Singleton(){singleleton=new Singleton(); }}
特点:这种写法是线程不安全的,他无法保证同时不被多个线程访问,适合在单线程环境下使用。
要想保证线程安全,可以参考下面三种写法:
1)使用synchronized关键字
class Singleton{private static Singleton singleleton=null;pulic static synchronized Singleton getInstance(){if(singleleton==null){ singleleton=new Singleton()}return singleleton;}private Singleton(){singleleton=new Singleton();}}
特点:相比上个方法,在静态方法前多加了个synchronized关键字,使同一时间只能有一个线程访问该代码块。
2)双重检查锁定
class Singleton{private static Singleton singleleton=null;pulic static Singleton getInstance(){if(singleleton==null){ synchronized(Singleton.class){ if(singleleton==null){ singleleton=new Singleton(); } }}return singleleton;}private Singleton(){singleleton=new Singleton();}}
特点:经过两次判定,第一次检测到实例为空时,增加同步,同步后再次检测到实例为空时,才创建对象实例。有效防止了在多线程环境下创建多个实例的问题。
3)静态内部类实现
class Singleton{private singleton(){}private static class SingleBuilder{ private static Singleton singleton=new Singleton(); //就像private int int=1}public static Singleton getInstance(){ return SingleBuilder.singleton;}}
特点:Java中静态内部类可以访问其外部类的成员属性和方法,同时java规定静态内部类只在首次调用时被加载,因此实现了懒汉式,所以他只被加载一次,所以是线程安全的
2.饿汉式:
class Singleton{private static Singleton singleleton=new Singleton();pulic static Singleton getInstance(){return singleleton;}private Singleton(){}}
特点:饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。
3.登记式:
public class Singleton { private static Map< String,Singleton> map = new HashMap< String,Singleton>(); static{ Singleton single = new Singleton(); map.put(single.getClass().getName(), single); } //保护的默认构造子 protected Singleton(){} //静态工厂方法,返还此类惟一的实例 public static Singleton getInstance(String name) { if(name == null) { name = Singleton.class.getName(); System.out.println("name == null"+"--->name="+name); } if(map.get(name) == null) { try { map.put(name, (Singleton) Class.forName(name).newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return map.get(name); } public static void main(String[] args) { Singleton3 single = Singleton.getInstance(null); } }
登记式单例实际上维护了一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从Map直接返回,对于没有登记的,则先登记,然后返回。 内部实现还是用的饿汉式单例。
4.使用volatile 关键字
class Singleton{ private static volatile Singleton Instance=null; public Singleton() { } public static Singleton getInstance(){ if(Instance==null){ synchronized (Singleton.class) { if (Instance == null) { Instance = new Singleton(); } } } return Instance; }}
volatile 保证在实例对象创建后快速通知其他线程该对象的实例已经存在,不需要重复创建了。
1 0
- java 单例模式的写法
- Java单例模式的写法
- Java单例模式的写法
- Java 的单例模式写法
- Java 单例模式的写法
- java单例模式写法
- java单例模式单写法
- Java设计模式之单例模式的写法
- 单例模式的写法
- 单例模式的写法
- 单例模式的写法
- 单例模式的写法
- 单例模式的写法
- 单例模式的写法
- java单例模式的7种写法
- Java:单例模式的七种写法
- Java 单例模式的七种写法
- Java:单例模式的七种写法
- 一种文献搜索的技巧
- 用筛法求100之内的所有素数
- Scala中的基本控制结构
- 日常潜水-20160927-微信企业号发送消息接口
- 跳跃问题
- Java单例模式的写法
- AngularJs学习笔记(一)
- 日常
- C语言之_双重指针、多文件、include、文件
- Leetcode 87 Scramble String
- iOS使用自签名证书实现HTTPS请求
- Unable to add window android.view.ViewRootImpl -- permission denied for this window type
- Java设计模式——模板方法模式(TEMPLATE METHOD PATTERN)
- JavaScript中的Array操作(ECMA5新特性)