java单例模式的四种实现方式
饿汉式、懒汉式、双重验证锁机制、静态内部类
饿汉式
饿汉式就是不管怎么样都会直接创建一个对象给你
public class SingletonErhan {
/**
* 单例模式之饿汉式
*/
private static SingletonErhan singletonErhan = new SingletonErhan();
private SingletonErhan(){
}
public static SingletonErhan getSingletonErhan(){
return singletonErhan;
}
}
测试类
public class TestDemo {
//测试饿汉式
@Test
public void testSingletonErhan(){
SingletonErhan singletonErhan = SingletonErhan.getSingletonErhan();
SingletonErhan singletonErhan1 = SingletonErhan.getSingletonErhan();
System.out.println(singletonErhan);
System.out.println(singletonErhan1);
}
}
打印信息

懒汉式
创建一个类
public class SingletonLahan {
/**
* 单例模式懒汉式
*/
private static SingletonLahan singletonLahan;
private SingletonLahan(){
}
public static SingletonLahan getSingletonLahan(){
if (singletonLahan == null){
singletonLahan = new SingletonLahan();
}
return singletonLahan;
}
}
先私有化一个静态对象,不设置任何值然后创建一个获取对象的共有静态方法当我们需要的时候就去直接调用这个共有静态方法先要判断对象是否为空,为空的话直接new一个对象赋值给室私有静态成员变量(相当于给对象初始化),因为是静态的只初始化一次,存放在栈中;
测试:
//测试懒汉模式
@Test
public void testSingletonLanHan(){
SingletonLahan singletonLahan = SingletonLahan.getSingletonLahan();
SingletonLahan singletonLahan1 = SingletonLahan.getSingletonLahan();
System.out.println(singletonLahan);
System.out.println(singletonLahan1);
}
双重验证
创建一个类
public class SingletonSycn {
/**
* 双重验证锁机制
*/
private static SingletonSycn singleton;
private SingletonSycn() {
}
public static SingletonSycn getSingleton() {
if (singleton == null) {
synchronized (SingletonSycn.class) {
if (singleton == null) {
singleton = new SingletonSycn();
}
}
}
return singleton;
}
}
我们需要使用到synchronized同步锁来阻止多线程的情况下产生的安全问题
第一个if是判断该对象是否为空,当一个线程进入到synchronized同步代码块中其他线程就只能在外面等待,此时再次进行判断对象是否为空是验证该对象是否被其它线程抢先进入并且初始化对象,如果有直接返回,如果没有进行初始化对象
测试:
//测试双重验证锁机制
@Test
public void testSingletonSycn(){
SingletonSycn singleton = SingletonSycn.getSingleton();
SingletonSycn singleton1 = SingletonSycn.getSingleton();
System.out.println(singleton);
System.out.println(singleton1);
}
静态内部类
public class SingletonClass {
/**
* 单例模式之匿名内部类
*/
private SingletonClass(){
}
private static class InnerClass{
private static SingletonClass singletonClass = new SingletonClass();
}
public static SingletonClass getSinletonClass(){
return InnerClass.singletonClass;
}
}
直接在内部类内部就把对象进行初始化,这样很安全。可以让创建次对象时无法直接去访问我们的私有内部类
测试
//测试私有匿名内部类
@Test
public void testSingletonClass(){
SingletonSycn singleton = SingletonSycn.getSingleton();
SingletonSycn singleton1 = SingletonSycn.getSingleton();
System.out.println(singleton);
System.out.println(singleton1);
}