单例&多线程

时间:2023-11-27 15:43:32

单例模式,最常见的就是饥饿模式,和懒汉模式,一个直接实例化对象,一个在调用方法时进行实例化对象。在多线程模式中,考虑到性能和线程安全问题,我们一般选择下面两种比较经典的单例模式,在性能提高的同时,又保证了线程安全。

  dubble check Instance    》》

  static Inner class   》》静态内部类模式,简单安全

下面看一下static Inner class的实现:

public class InnerSingleton {

    private static class Singletion {
private static Singletion single = new Singletion();
} public static Singletion getInstance(){
return Singletion.single;
}
} 这种单例是最实用,最安全的一种单例实现方式。里面有一个静态的内部类,实例化一个静态的单例,然后提供一个返回对象的接口,调用后
直接返回这个单例。 下面接着看一下dubble check Instance的实现:
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();
}
} 看一下上面这段代码,他在实例化对象的时候,进行了两次判断,如果后面的判断不进行,那么最后打印的
hashCode是不一样的,但是实际上我们需要的是一个实例化对象,这种方式比较麻烦,不建议使用。