1、单线程的单件模式:
private static Singleton singleton;
/**
* 这种方式在多线程中是有问题的,可能产生多个实例
*/
public static Singleton getInstance()
{
if (singleton == null)
{
singleton = new Singleton();
}
return singleton;
}
```
# 2、多线程(线程同步)的单件模式:
/**
* 使用 synchronized 迫使每个线程在进入这个方法前,都要等待其他线程离开这个方法。
*
* 缺点是:只有第一次执行的时候,才真正需要同步,一旦实例化好,就不需要再同步了,造成性能累赘
*
* 如果这种累赘对程序没多大影响,那就用
*/
public static synchronized Singleton getInstance()
{
if (singleton == null)
{
singleton = new Singleton();
}
return singleton;
}
# 3、急切的单件模式:
// 在JVM加载这个类的时候,马上创建此类实例,这种急切创建实例的方式,适用于那种总是创建和使用实例的程序
private static Singleton singleton = new Singleton();
public static Singleton getInstance()
{
return singleton;
}
# 4、双重加锁的单件模式:
private volatile static Singleton singleton;
/**
* 利用双重加锁,这样只有在第一次实例化时,才会加锁
*
* 如果性能是你关心的重点,这个方法适合,但是,此方式不适用于1.4及更早的版本中。1.5之后可以达到正常的单例效果。
*/
public static Singleton getInstance()
{
if (singleton == null)
{
synchronized (Singleton.class)
{
if (singleton == null)
{
singleton = new Singleton();
}
}
}
return singleton3;
}
# 5、如果类自给自足,不依赖于复杂的初始化,可以把类的变量和方法都置为静态,把类当成单件使用。
# 6、类加载器:两个类加载器可能有机会各自创建自己的单例
每个类加载器都定义了一个命名空间,如果有两个以上的类加载器,不同的类加载器可能会加载同一个类,造成多个单件。
这时候就需要小心了,可以通过自行指定类加载器,并指定同一个类加载器
# 7、枚举:不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象
public enum Singleton
{
INSTANCE;
public void whateverMethod()
{
}
}
# 8、内部类的形式:
public class Singleton
{
private static class SingletonHolder
{
private static final Singleton INSTANCE = new Singleton();
}
// 只有此方法被调用,SingletonHolder类才会被加载。能做到单例并且延迟加载。
public static final Singleton getInstance()
{
return SingletonHolder.INSTANCE;
}
}
---
** 如果是类的形式,都需要私有构造器 **
private Singleton()
{
}
** 本人最常用的是第4和第8种,如果你的IDE使用的是AndroidStudio,可以定义一个Live Templates。如下:**
(1)打开Settings -> Editor -> Live Templates
(2)添加一个Live Template,这里设定名称为single_yyq
(3)在No applicable contexts. ** Define **,点击Define,勾选Java
(4)在Template text中输入:
private static $classname$ instance;
private $classname$()
{
}
public static $classname$ getInstance()
{
if (instance == null)
{
synchronized ($classname$.class)
{
if (instance == null)
{
instance = new $classname$();
}
}
}
return instance;
}
(5)点击右边的Edit variables,将classname的类型改为className(),大功告成,Live Templates的用处不言而喻啦,有兴趣可以Google一下。
![test.gif](https://img.haomeiwen.com/i2691199/8529b1a52470c995.gif?imageMogr2/auto-orient/strip)
网友评论