一、概念
一般采用单例模式就是为了满足“只创建一个类”的需要。
单例模式有两个特点:
(1)一个类仅有一个实例
(2)仅有一个全局访问点
二、写法
1、饿汉式
所谓饿汉式,是指这个类的实例在类加载阶段就已经创建出来了。
public class Singleton1 {
//在类的内部实例化一个实例
private static final Singleton1 instance = new Singleton1();
//隐藏构造方法
private Singleton1() {
}
//对外开放一个获取实例的方法
public static Singleton1 getInstance(){
return instance;
}
}
当然也可以使用static代码块。(注意这里的final,看网上有各种写法,加或者不加的都有,我认为这里可以加,这样getInstance方法里就不需要判空了)
这种方式虽然能够有效避免线程安全的问题,但是却可能造成不必要的浪费,因为也许这个实例并不需要用到,或者就用到一两次,却要一直占用内存。
2、静态内部类
public class InnerClassSingleton {
//在静态内部类中实例化对象
private static class SingletonHolder{
private static final InnerClassSingleton instance = new InnerClassSingleton();
}
//隐藏构造方法
private InnerClassSingleton(){
}
//对外提供访问方法
public static final InnerClassSingleton getInstance() {
return SingletonHolder.instance;
}
}
3、懒汉式
所谓懒汉式,就是在使用时才加载,比较“懒一些”。
public class Singleton2 {
private static Singleton2 instance;
private Singleton2(){
}
public static Singleton2 getInstance(){
//在对象被使用时才实例化
if (instance == null)
instance = new Singleton2();
return instance;
}
}
注意:加上synchronized关键字就可以保证线程安全。
public class Singleton2 {
private static Singleton2 instance;
private Singleton2(){
}
public static synchronized Singleton2 getInstance(){
//在对象被使用时才实例化
if (instance == null)
instance = new Singleton2();
return instance;
}
}
4、当然上述方式效率比较低,因为synchronized锁的范围太大了
public class Singleton2 {
private static Singleton2 instance;
private Singleton2(){
}
public static Singleton2 getInstance(){
//在对象被使用时才实例化
synchronized (Singleton2.class){
if (instance == null)
instance = new Singleton2();
return instance;
}
}
}
这样就缩小了锁的范围,但是这种方式依然存在问题,因为Java内存模型的机制,程序可能会崩溃,因此就要用到volatile。
5、使用volatile
public class Singleton2 {
private static volatile Singleton2 instance;
private Singleton2(){
}
public static Singleton2 getInstance(){
//在对象被使用时才实例化
if (instance == null){
synchronized (Singleton2.class){
if (instance == null)
instance = new Singleton2();
return instance;
}
}
}
}
6、枚举式
public enum Singleton3 {
INSTANCE;
Singleton() {
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。