单例模式怎么写( 二 )


3. java几种单例模式写法 懒汉模式public class SingletonDemo {private static SingletonDemo instance;private SingletonDemo(){}public static SingletonDemo getInstance(){if(instance==null){instance=new SingletonDemo();}return instance;}}2. 线程安全的懒汉模式public class SingletonDemo {private static SingletonDemo instance;private SingletonDemo(){}public static synchronized SingletonDemo getInstance(){if(instance==null){instance=new SingletonDemo();}return instance;}}3. 饿汉模式public class SingletonDemo {private static SingletonDemo instance=new SingletonDemo();private SingletonDemo(){}public static SingletonDemo getInstance(){return instance;}}4. 静态类内部加载public class SingletonDemo {private static class SingletonHolder{private static SingletonDemo instance=new SingletonDemo();}private SingletonDemo(){System.out.println("Singleton has loaded");}public static SingletonDemo getInstance(){return SingletonHolder.instance;}}5.双重校验锁法public class SingletonDemo {private volatile static SingletonDemo instance;private SingletonDemo(){System.out.println("Singleton has loaded");}public static SingletonDemo getInstance(){if(instance==null){synchronized (SingletonDemo.class){if(instance==null){instance=new SingletonDemo();}}}return instance;}} 。
4. android 几种单例模式的写法 先不论单例模式的写法,有些方面是相同的,比如都需要将唯一的对象设置为static的,都需要将构造方法private化,代码如下:public class MyInstance { private static MyInstance instance; private MyInstance(){}}第一种:最原始的单例模式,代码如下:public static MyInstance getInstance(){ if(instance==null){ instance=new MyInstance();} return instance;}多线程并发时,可能会出现重复new对象的情况,因此不提倡使用 。
第二种:将整个方法块进行加锁,保证线程安全 。public static synchronized MyInstance getInstance(){ if(instance==null){ instance=new MyInstance();} return instance;}这种代码下,每条线程都会依次进入方法块内部,虽然实现了单例,但是影响了运行效率,可以使用但是也不怎么提倡 。
第三种:进一步优化的方法 。public static MyInstance getsInstance(){ synchronized (MyInstance.class){ if(instance==null){ instance=new MyInstance(); return instance;}else{ return instance;}}}这种方式只是第二种方法的一种优化,但是优化有限 。
(以下的几种方法比较推荐使用)第四种:双层判断加锁,效率影响小且保证了线程安全 。public static MyInstance getsInstance() { if (instance == null) { synchronized (MyInstance.class) { if(instance==null){ instance=new MyInstance();}}} return instance;}这种方法是对第二种和第三种方法的进一步优化,比较推荐使用 。
第五种:内部类实现单例,不用线程锁来实现效率的提升 。public class MyInstance { private MyInstance() {} public static MyInstance getInstance(){ return MyInstanceHolder.instance;} private static class MyInstanceHolder{ private static MyInstance instance=new MyInstance();}}在内部类中new对象,再将内部类的对象返回,这种方法是使用了java中class加载时互斥的原理来实现了线程的安全 。
不加线程锁也使得运行效率不会受到较大的影响 。比较提倡 。
5. 如何正确地写出单例模式 当被问到要实现一个单例模式时,很多人的第一反应是写出如下的代码,包括教科书上也是这样教我们的 。
1234567891011public class Singleton {private static Singleton instance;private Singleton (){}public static Singleton getInstance () {if (instance == null ) {instance = new Singleton();}return instance;}}这段代码简单明了,而且使用了懒加载模式,但是却存在致命的问题 。当有多个线程并行调用 getInstance() 的时候,就会创建多个实例 。
也就是说在多线程下不能正常工作 。懒汉式,线程安全为了解决上面的问题,最简单的方法是将整个 getInstance() 方法设为同步(synchronized) 。