千家信息网

Java单例如何实现

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇文章将为大家详细讲解有关Java单例如何实现,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。单例模式,顾名思义,就是全局只保存有一个实例并且能够避免用户去手动实例
千家信息网最后更新 2025年02月01日Java单例如何实现

这篇文章将为大家详细讲解有关Java单例如何实现,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

单例模式,顾名思义,就是全局只保存有一个实例并且能够避免用户去手动实例化,所以单例模式的各种写法都有一个共同点,不能通过new关键字去创建对象,因此,如果能够通过构造方法实例化,那么就一定要将其声明为私有。

饿汉式

public class PersonResource {    public static final PersonResource PERSON_RESOURCE_SINGLETON = new PersonResource();    private PersonResource(){}    public  static PersonResource getInstance() {        return PERSON_RESOURCE_SINGLETON;    }}

这种方式可以说是最安全,也最简单的了,但却有一个缺点,那就是无论这个实例有没有被使用到,都会被实例化,颇有些浪费资源

懒汉式一

既然前一种方法有些浪费资源,那就换一种写法,让类在被调用的时候实例化

public class PersonResource {    private static PersonResource personResourceSingleton;    private PersonResource() {    }    public static PersonResource getPersonResourceSingleton(){        if(null==personResourceSingleton){            personResourceSingleton = new PersonResource();        }        return personResourceSingleton;    }}

这种方式能够在需要用到该实例的时候再初始化,也能够在单线程下很好的运行,但如果是多线程就容易出现问题了。

懒汉式二

public class PersonResource {    private static PersonResource personResourceSingleton;    private PersonResource() {    }    public static PersonResource getPersonResourceSingleton(){        if(null==personResourceSingleton){            personResourceSingleton = new PersonResource();        }        return personResourceSingleton;    }}

多线程之所以会出现问题,是因为多个线程能够并发执行getPersonResourceSingleton方法,从而导致在判断是否为空时出现问题。

既然如此,加上锁 ,使其互斥即可。这里又出现了一个问题,每次获取实例的时候都需要加锁解锁,而当一个实例已经被产生后,再加锁就有些多余了;

懒汉式三(双重检查)

public class PersonResource {    private PersonResource(){    }    private volatile static PersonResource personResource;    public  static PersonResource getInstance(){        if(personResource==null){            synchronized (PersonResource.class){                if(personResource==null){                    personResource = new PersonResource();                }            }        }        return personResource;    }}

既然实例确定产生后不再需要加锁,那我们在获取锁前先判断一次是否已经有实例存在就可以解决问题了

静态内部类

public class PersonResource {    private PersonResource(){}    private static class PersonResourceHolder{        public static PersonResource personResourceSingleton = new PersonResource();    }    public static PersonResource getInstance(){        return PersonResourceHolder.personResourceSingleton;    }}

除了双重检查能够保证安全的单例外,用一个静态内部类去持有单例也是可以的,静态内部类保证了不会随外部类的加载而加载,这保证了延迟加载,同时在加载该类的时候就实例化单例,保证了线程安全;

枚举

public enum PersonResource {    /**     * PersonResource单例     */    personResource;    public void setPersonResource(){    }}

关于"Java单例如何实现"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

0