本文共 2723 字,大约阅读时间需要 9 分钟。
分享最常用的单例模式。
饿汉式——简单粗暴在初始化的时候就加载。
package com.example.visualizerview;/** * 饿汉式 * @author Zxt * */public class Singleton { private static Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return instance; }}在初始化速度非常快,占用内存较小时适用,不会出现线程安全问题。
懒汉式——延迟加载。
package com.example.visualizerview;/** * 懒汉式 * @author Zxt * */public class Singleton { public static Singleton instance = null; private Singleton() { } public static Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; }}在需要的时候才进行加载。
多线程:
上面介绍的两种单例模式都是在最基本常规(单线程)的情况下的写法。
多线程的情况下:
饿汉式不会出现问题应为JVM只加载一次单例类。
懒汉式则可能出现重复创建的单例对象的情况原因如下:
1,常见的解决办法:
或:
public class Singleton { public static Singleton instance = null; private Singleton() { } public static synchronized Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; }}这种写法每次调用getInstance()时都进行同步,造成不必要的开销。
2,提高性能的写法:
3,静态内部类写法——线程安全:
4,枚举单例:
/** * 枚举单例写法 * @author Zxt * */public enum Singleton { instance; public void doSomething() { }}使用枚举单例:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Singleton instance = Singleton.instance; instance.doSomething();}
实际使用:
上面说的内部类和枚举的写法实际中用的其实不多,下面上一段我项目中用的单例写法:
public class SleepController { private static final String TAG = "SleepController"; private static Context mContext; private ManagerService mManagerService; private MusicService.State mPlayState; private Handler mHandler; private HandlerThread mThread; private TimeReminderReceiver timeReminderReceiver; private static SleepController mInstance; public SleepController(Context applicationContext,ManagerService mManagerService) { mContext = applicationContext; this.mManagerService = mManagerService; mThread = new HandlerThread("background"); mThread.start(); mHandler = new Handler(mThread.getLooper()); //定时提醒 timeReminderReceiver = new TimeReminderReceiver(); IntentFilter timeReminderFilter = new IntentFilter(); timeReminderFilter.addAction(GlobalConstant.BROADCAST_TIME_REMINDER); mContext.registerReceiver(timeReminderReceiver, timeReminderFilter); } public static SleepController getInstances(Context context,ManagerService mManagerService) { if (mInstance == null) { synchronized (SleepController.class) { if (mInstance == null) { mInstance = new SleepController(context.getApplicationContext(),mManagerService); } } } return mInstance; }