单例的实现
程序员文章站
2022-03-07 16:04:31
...
很多java面试喜欢考单例模式,网上也一大堆文章。在这里也自己实现一次,作个纪念。
import java.io.*;
/**
* User: sunlong
* Date: 13-9-29
* Time: 下午3:55
*/
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
}
/**
* 饿汉式
* 非线程安全实现
*/
class Singleton2{
private Singleton2(){}
private static Singleton2 singleton;
public static Singleton2 getInstance(){
if(singleton == null){
singleton = new Singleton2();
}
return singleton;
}
}
/**
* 线程安全,但性能很糟糕
*/
class Singleton3{
private Singleton3(){}
private static Singleton3 singleton;
public static Singleton3 getInstance(){
synchronized (Singleton3.class){
if(singleton == null){
singleton = new Singleton3();
}
}
return singleton;
}
}
/**
* 双检查锁
* 可能会失效,因为同步块外面的if (singleton == null)可能看到已存在,但不完整的实例。
* 一篇参考文章
* http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
*/
class Singleton4{
private Singleton4(){}
private static Singleton4 singleton; //JDK5.0以后版本若singleton为volatile则可行
public static Singleton4 getInstance(){
if(singleton == null){
synchronized (Singleton4.class){
if(singleton == null){
singleton = new Singleton4();
}
}
}
return singleton;
}
}
/**
* 使用内部类实现延迟加载
* 线程安全
*/
class Singleton5 {
private static class Singleton5Holder {
final static Singleton5 INSTANCE = new Singleton5();
}
private Singleton5 (){
}
public static Singleton5 getInstance() {
return Singleton5Holder.INSTANCE;
}
}
/**
* 为了使Singleton类变成可序列化的(serializable),
* 仅仅实现Serializable接口是不够的。为了维护 Singleton的单例性,你必须给Singleton类提供一个readResolve方法,
* 否则的话,一个序列化的实例,每次反序列化的时候都会产 生一个新的实例。Singleton 也不会例外。
*/
class Singleton6 implements Serializable{
private static Singleton6 singleton = new Singleton6();
private Singleton6(){}
public static Singleton6 getInstance(){
return singleton;
}
// private Object readResolve() throws ObjectStreamException {
// return singleton;
// }
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\Singleton.obj"));
Singleton6 singleton = Singleton6.getInstance();
objectOutputStream.writeObject(singleton);
objectOutputStream.close();
//反序列化
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\Singleton.obj"));
Singleton6 singleton2 = (Singleton6)objectInputStream.readObject();
objectInputStream.close();
//比较是否原来的实例
System.out.println(singleton==singleton2);
}
}