转载博主:thankyou
https://blog.csdn.net/twj13162380953/article/details/53869983
理解:
饿汉式获取实例的步骤简单所以线程更安全。懒汉式只是不会在类加载时即创建静态对象而效率略高,而因此也导致有判断是否已创建对象环节会使线程变得不安全,需要加同步锁才能解决该问题。
单例模式
解决的问题:保证一个类在内存中的对象唯一性.
比如:多程序读取一个配置文件时,建议配置文件封装成对象。会方便操作其中数据,又要保证多个程序读到的是同一个配置文件对象,
就需要该配置文件对象在内存中是唯一的。
如何保证对象唯一性呢?
思想:
1,不让其他程序创建该类对象。
2,在本类中创建一个本类对象。
3,对外提供方法,让其他程序获取这个对象。
步骤:
1,因为创建对象都需要构造函数初始化,只要将本类中的构造函数私有化,其他程序就无法再创建该类对象;
2,就在类中创建一个私有并静态的本类的对象;
3,定义一个方法,返回该对象,让其他程序可以通过方法就得到本类对象。(作用:可控)
代码体现:
1,私有化构造函数;
2,创建私有并静态的本类对象;
3,定义公有并静态的方法,返回该对象。
饿汉模式:
-
class Single{
-
private Single(){} //私有化构造函数。
-
private static Single s = new Single(); //创建私有并静态的本类对象。
-
public static Single getInstance(){ //定义公有并静态的方法,返回该对象。
-
return s;
-
}
-
}
//懒汉式:延迟加载方式。使用到的时候才回去初始化该对象
-
class Single2{
-
private Single2(){}
-
private static Single2 s = null;
-
public static Single2 getInstance(){
-
if(s==null)
-
s = new Single2();
-
return s;
-
}
-
}
在多线程模式中,考虑到性能和线程安全问题,我们一般会选择下面两种比较经典的单例模式,在性能提高的同时,又保证了线程的安全.
1.static inner Class
2.dubble check instance
(饿汉模式)static inner Class-内部静态类的形式
-
public class Singletion {
-
-
private static class InnerSingletion {
-
private static Singletion single = new Singletion();
-
}
-
-
public static Singletion getInstance(){
-
return InnerSingletion.single;
-
}
-
-
}
(懒汉模式) dubble check instance-为确保线程安全,需要两次check
-
public class DubbleSingleton {
-
-
private static DubbleSingleton ds;
-
-
public static DubbleSingleton getDs(){
-
if(ds == null){
-
try {
-
//模拟初始化对象的准备时间...
-
Thread.sleep(3000);
-
} catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
synchronized (DubbleSingleton.class) {
-
if(ds == null){
-
ds = new DubbleSingleton();
-
}
-
}
-
}
-
return ds;
-
}
-
-
public static void main(String[] args) {
-
Thread t1 = new Thread(new Runnable() {
-
@Override
-
public void run() {
-
System.out.println(DubbleSingleton.getDs().hashCode());
-
}
-
},"t1");
-
Thread t2 = new Thread(new Runnable() {
-
@Override
-
public void run() {
-
System.out.println(DubbleSingleton.getDs().hashCode());
-
}
-
},"t2");
-
Thread t3 = new Thread(new Runnable() {
-
@Override
-
public void run() {
-
System.out.println(DubbleSingleton.getDs().hashCode());
-
}
-
},"t3");
-
-
t1.start();
-
t2.start();
-
t3.start();
-
}
-
-
}
输出结果:
-
792363696
-
792363696
-
792363696