正宗的懒汉式单例设计模式

一、懒汉式单例设计模式1:
class Singleton {
private static Singleton instance;  

private Singleton() {
System.out.println("*********构造*************");
}

public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}

public void print() {
System.out.println(Thread.currentThread().getName() + " = Test Singleton!");
}
}

public class TestSingle {
public static void main(String[] args) {
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
}
}
此时运行程序之后的输出结果如下:
*********构造*************
*********构造*************
Thread-1 = Test Singleton!
*********构造*************
*********构造*************
Thread-5 = Test Singleton!
*********构造*************
Thread-3 = Test Singleton!
Thread-2 = Test Singleton!
Thread-4 = Test Singleton!
Thread-0 = Test Singleton!
Thread-6 = Test Singleton!
分析发现;该类中并不是只实例化了一个对象,这与单例设计模式的概念相违背。查阅相关资料发现:当类的属性没有用volatitle关键字修饰时,在多线程运行的环境中,每个线程操作的都是该属性的一个副本,当某个线程更改了该属性的值之后,到该属性的值同步改变之后是需要时间的(即是有延迟的),所以出现了该单例类实例化了好几个对象的情况。线程操作副本的示例图如下:


当用volatile修饰属性之后,则这个属性一旦设置后,将自动立刻进行原始变量的同步,不会出现任何的延时

二、修改后正宗的懒汉式单例设计模式如下:
class Singleton {
private volatile static Singleton instance;   //volatile修饰该属性后,表示这个属性一旦设置后,将自动立刻进行原始变量的同步

private Singleton() {                     //既然是单例,构造方法就要私有化
System.out.println("**********构造***************");
}

public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {   //只是此部分操作进行了同步
if (instance == null) {       //每个线程进来之后要判断一下instance是不是为null
instance = new Singleton();
}
}
}
return instance;
}

public void print() {
System.out.println(Thread.currentThread().getName());
}
}

public class TestSingle {
public static void main(String[] args) {
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
}
}
运行程序后输出结果如下:
**********构造***************
Thread-0
Thread-1
Thread-3
Thread-2
Thread-4
Thread-5
Thread-6
至此正宗的懒汉式单例设计模式就写出来了
三、饱汉式单例设计模式
class Singleton {
private static Singleton instance = new Singleton();   //直接将该对象实例化好

private Singleton() {}

public static Singleton getInstance() {
return instance;
}

public void print() {
System.out.println(Thread.currentThread().getName());
}
}

public class TestSingleton {
public static void main(String[] args) {
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
new Thread(() -> {
Singleton.getInstance().print();
}).start();
}
}
开发中单例的概念应用比较多

猜你喜欢

转载自1210344340.iteye.com/blog/2387651