分享最常用的单例模式。
饿汉式——简单粗暴在初始化的时候就加载。
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;
}