定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
1、懒汉式
public class Apple{
private static Apple instance;
public static Apple getInstance(){
if(instance == null){
instance = new Apple();
}
return instance;
}
}
上述代码在单线程环境中没问题,在多线程环境中可能会产生多个实例,所以要考虑线程安全,用同步块,代码如下:
public class Apple{
private static Apple instance;
public static Apple getInstance(){
synchronized(this){
if(instance == null){
instance = new Apple();
}
return instance;
}
}
}
但仔细审查代码发现,实例在第一次创建之后同步块里的代码就没有必要访问了,也就是说,同步化可以不要执行了,所以同步代码之前可以再次检查实例是否存在,即双重检测锁定模式,代码如下:
public class Apple{
private static Apple instance;
public static Apple getInstance(){
if(instance==null){// 一重检测
synchronized(this){
if(instance == null){//二重检测
instance = new Apple();//实例化
}
return instance;
}
}
}
}
在JDK1.5之前,双重检测锁定是这么写的,但是有问题。当线程1执行到实例化这一步,即进入Apple()构造函数之前,线程2对instance进行判断,instance确实不为null,但也很可能只实例化了一部分,所以对线程2来说,此时获取的instance很可能只是实例化了一部分的对象。所以要保证instance对所有线程可见,用volatile关键字,代码如下:
public class Apple{
private volatile static Apple instance;
public static Apple getInstance(){
if(instance==null){
synchronized(this){
if(instance == null){
instance = new Apple();
}
return instance;
}
}
}
}
2、饿汉式单例
public class Apple{
private static Apple instance = new Apple();
public static Apple getInstance(){
return instance;
}
}
}