单例模式
一个类在软件整个系统中,只有一个实例对象。单例模式阻止其它对象复制自己单例对象的副本,确保始终只有一个实例。
(一)单线程的单例模式:
public class Singleton {
private static Singleton obj = null;
private Singleton(){}
public static Singleton getInstance() throws InterruptedException
{
if(obj == null)
{
Thread.sleep(100);
obj = new Singleton();
}
return obj;
}
public void output()
{
System.out.println(this.hashCode());
}
}
在单线程中,上面代码在运行中,是没有任何问题的;但是如果在多线程中,就容易有多个实例产生。
(二)多线程的单例模式:
public class ThreadSingleton {
private static ThreadSingleton obj = null;
private ThreadSingleton() {
}
public static ThreadSingleton getInstance() throws InterruptedException {
if (obj == null) {
synchronized (ThreadSingleton.class) {
if (obj == null) {
obj = new ThreadSingleton();
}
}
}
return obj;
}
public void output()
{
System.out.println(this.hashCode());
}
}
在优化型编译器中,上面的代码却不能正常的工作,为什么呢?最明显的原因是,初始化实例的写入操作和实例字段的写入操作能够被编器或者缓冲区重排序,重排序可能会导致返回部分构造的一些东西。就是我们读取到了一个没有初始化的对象等等。那怎么实现一个最好的单例模式呢?
(三)单例模式最终代码:
public class SingletonObject {
public void output()
{
System.out.println(this.hashCode());
}
}
public class ThreadSingletonFactory {
private static SingletonObject obj = new SingletonObject();
public static SingletonObject getInstatnce()
{
return obj;
}
}
我们可以利用辅助类,将需要使用的单例类静态化为辅助类的成员变量,这样我们就不用过多考虑线程的问题了。任何需要该单例的地方,我们只需要使用这个辅助类就可以解决问题。