dB进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序 。
e此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了 。
正确改进(使用内部类):
JVM内部的机制能够保证当一个类被加载的时候 , 这个类的加载过程是线程互斥的,JVM能够帮我们保证instance只被创建一次,
并且会保证把赋值给instance的内存初始化完毕 , 这样我们就不用担心上面的问题 。
同时该方法也只会在第一次调用的时候使用互斥机制,这样就解决了低性能问题
public?class?Singleton?{??
??
/*?私有构造方法,防止被实例化?*/??
private?Singleton(){
}
/*?此处使用一个内部类来维护单例?*/??
private?static?class?SingletonFactory?{??
private?static?Singleton?instance?=?new?Singleton();??
}
/*?获取实例?*/??
public?static?Singleton?getInstance()?{??
return?SingletonFactory.instance;??
}
/*?如果该对象被用于序列化,可以保证对象在序列化前后保持一致?*/??
public?Object?readResolve()?{??
return?getInstance();??
}
}
其实说它完美 , 也不一定 , 如果在构造函数中抛出异常 , 实例将永远得不到创建,也会出错????
第二种改进:
因为我们只需要在创建类的时候进行同步,所以只要将创建和getInstance()分开,
单独为创建加synchronized关键字,也是可以的
public class Singleton{
private static Singletoninstance=null;
private Singleton(){}
privatestatic synchronized void Init(){
if(instance==null)
instance=new Singletion();
}
public static Singleton getInstance(){
if(instance==null){
Init();
}
return instance;
}
}
3.登记式单例类
import java.util.HashMap;
import java.util.Map;
//登记式单例类.
//类似Spring里面的方法,将类名注册,下次从里面直接获取 。
public class Singleton3 {
private static MapString,Singleton3 map = new HashMapString,Singleton3();
static{
Singleton3 single = new Singleton3();
map.put(single.getClass().getName(), single);
}
//保护的默认构造子
protected Singleton3(){}
//静态工厂方法,返还此类惟一的实例
public static Singleton3 getInstance(String name) {
if(name == null) {
name = Singleton3.class.getName();
System.out.println("name == null"+"---name="+name);
}
if(map.get(name) == null) {
try {
map.put(name, (Singleton3) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
//一个示意性的商业方法
public String about() {
return "Hello, I am RegSingleton.";
}
public static void main(String[] args) {
Singleton3 single3 = Singleton3.getInstance(null);
System.out.println(single3.about());
}
}
单例模式代码怎么写? 单例模式(Singleton) ,属于最常见的设计模式之一java与模式代码,大部分系统都会用到java与模式代码,目的是为了维护系统中唯一的一个实例 。
可分为eager模式java与模式代码,示例代码如下:
Java代码
1.class EagerSingleton{
2. private static final EagerSingleton m_instance = new EagerSingleton();
3. private EagerSingleton(){}
4. public static EagerSingleton getInstance(){
5. return m_instance;
推荐阅读
- 手机全部数据怎么换回来,手机全部数据怎么换回来呢
- 安卓开发滑动选择器,安卓开发滑动选择器怎么用
- 包含sapcopy的词条
- 魔域4399单机游戏,4399魔域104无敌版
- python曲面拟合函数 python拟合曲线求方程
- css中文字居中的样式,css中文字居中对齐怎么设置
- 云平台虚拟机原理,云平台虚拟机原理
- python爬虫1001无标题,python爬虫题库
- php获取数据库总行数 php获取数据库用户id