(1)饿汉式(线程安全)
该方式没有线程安全问题,当类被卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存。
package cn.edu.bjfu.main;
public class MainTest {
public static void main(String[] args) {
Teacher t1 = Teacher.getInstance();
Teacher t2 = Teacher.getInstance();
System.out.println(t1==t2);
}
}
class Teacher {
//本类创建一个对象
private static Teacher t = new Teacher();
//不让别人创建对象
private Teacher() {}
//使外界可以通过类名. 来调用
public static Teacher getInstance( ) {
return t;
}
}
(2)懒汉式(线程不安全的)
package cn.edu.bjfu.main;
public class MainTest {
public static void main(String[] args) {
Teacher t1 = Teacher.getInstance();
Teacher t2 = Teacher.getInstance();
System.out.println(t1==t2);
}
}
class Teacher {
//本类创建一个对象
private static Teacher t = null;
//不让别人创建对象
private Teacher() {}
//使外界可以通过类名. 来调用
public static Teacher getInstance() {
if(t == null) {
t = new Teacher();
}
return t;
}
}
因此在某些特定条件下会节约了内存。在多线程环境中,这种实现方法是完全错误的,根本不能保证单例的状态。
(3)懒汉式(优化为线程安全)
package cn.edu.bjfu.main;
public class MainTest {
public static void main(String[] args) {
Teacher t1 = Teacher.getInstance();
Teacher t2 = Teacher.getInstance();
System.out.println(t1==t2);
}
}
class Teacher {
//本类创建一个对象
private static Teacher t = null;
//不让别人创建对象
private Teacher() {}
//使外界可以通过类名. 来调用
public static synchronized Teacher getInstance() {
if(t == null) {
t = new Teacher();
}
return t;
}
}
在多线程情形下,synchronized方法通常效率低。
(4)DCL双检锁机制改进优化懒汉式
package cn.edu.bjfu.main;
public class MainTest {
public static void main(String[] args) {
Teacher t1 = Teacher.getInstance();
Teacher t2 = Teacher.getInstance();
System.out.println(t1==t2);
}
}
class Teacher {
//本类创建一个对象
private static Teacher t = null;
//不让别人创建对象
private Teacher() {}
//使外界可以通过类名. 来调用
public static Teacher getInstance() {
if(t == null) {
synchronized (Teacher.class) {
//某个线程取到了类的锁,实例化对象前第二次检查t是否已经被实例化出来,如果没有,new一个。
if(t == null) {
t = new Teacher();
}
}
}
return t;
}
}