Java-java单例模式(懒加载)最好的实现方式?

发布于 2016-11-25 06:43:09 字数 441 浏览 2187 评论 9

请问大家都知道java的懒加载单例模式有哪些实现方式?我提出两种,一个是内部类实现方式:

public class Manager {  

private Manager() {

}

public static Manager getInstance() {
return ManagerHolder.instance;
}

private static class ManagerHolder {
private static final Manager instance = new Manager();
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

清晨说ぺ晚安 2017-10-17 20:57:35

饿汉的获取实例是静态的,在自己被加载时即被实例化,单从资源利用效率角度来讲,这个比懒汉式单例类稍差些。从速度和反应时间角度来讲,则比懒汉式单例类稍好些。然而,懒汉式单例类在实例化时,必须处理好在多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源初始化很有可能耗费时间。这意味着出现
多线程同时首次引用此类的机率变得较大。

夜无邪 2017-09-27 22:02:10

第一种好,因为第二种用到了同步,对多线程不利。
此外jdk1.5之后还有更简单的用violate和double locking来实现

想挽留 2017-07-11 16:06:58

 /**
* @author Administrator
* 没错的话应该是这样的
*/
public class Manager
{
private static Manager manager;
private Manager()
{}
public static Manager getInstance()
{
return (manager==null)?new Manager():manager;
}
}

甜柠檬 2017-07-09 22:22:11

另外还有一个是:登记式,将实例存放在Map中,未登记的先登记,已经登记的直接取用。
(例子是:《Java与模式》中的,建议去看看这本书,里面讲的很清楚)
[上面两个:
饿汉模式:在自己被加载时就将自己实例化
实例是static final类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性
懒汉模式:主要是将实例化的过程抽象出来 放在一个sychronized方法中执行。
在类加载时不创建单例实例。只在请求实例的时候才创建,并且不重复创建该类的实例。只不过在高并发的情况下,饿汉比懒汉速度快些。(个人认为2个方式都比较好)]

登记式:例子

 public class RegSingleton {
/**
* 登记薄,用来存放所有登记的实例
*/
private static Map<String, RegSingleton> m_registry = new HashMap();
//在类加载的时候添加一个实例到登记薄
static {
RegSingleton x = new RegSingleton();
m_registry.put(x.getClass().getName(), x);
}
/**
* 受保护的默认构造方法
*/
protected RegSingleton() {
}
/**
* 静态工厂方法,返回指定登记对象的唯一实例;
* 对于已登记的直接取出返回,对于还未登记的,先登记,然后取出返回
* @param name
* @return RegSingleton
*/
public static RegSingleton getInstance(String name) {
if (name == null) {
name = "RegSingleton";
}
if (m_registry.get(name) == null) {
try {
m_registry.put(name, (RegSingleton) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return m_registry.get(name);
}
/**
* 一个示意性的商业方法
* @return String
*/
public String about() {
return "Hello,I am RegSingleton!";
}
}

甜柠檬 2017-02-26 13:38:38

单例模式

之前看到过一个对单例模式各种写法的分析!受益匪浅!推荐!
引用原文中的一段话:
单例模式的写法有很多,在开发设计工作时,应当既要考虑到需求可能出现的扩展与变化,也应当避免“幻影需求”导致无谓的提升设计、实现复杂度,最终反而带来工期、性能和稳定性的损失。设计不足与设计过度都是危害,所以说没有最好的单例模式,只有最合适的单例模式。

清晨说ぺ晚安 2017-02-15 02:59:29

考虑到类的继承所造成的隐患,可以将singleton模式的类用final关键字修饰。
即以如下的方式创建
public final class Singleton{
//...
}

泛泛之交 2017-01-26 13:30:19

非线程安全的:

 public class Singleton {
private static Singleton instance;

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

private Singleton() {}
public static void main( String [] args ) {
Singleton instance = Singleton.getInstance();
// ... manipulate instance
}

}

线程安全的:

 public class Singleton {
private static Singleton instance;

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

private Singleton() {}
public static void main( String [] args ) {
Singleton instance = Singleton.getInstance();
// ...
}
}

虐人心 2017-01-09 06:11:09

java 5之后用enum是最好的方法--effective java

以下是用楼主的例子改的enum的方法:

public enum Manager {
    INSTANCE

 private Manager() {
//do something if needed
}

public void someMethod(){
//do something
}

public static void someStaticMethod(){
//do something
}
}

如果要invoke的话可以这样:

Manager.INSTANCE.someMethod();
Manager.someStaticMethod();

这样做的好处就是不用写readResolve方法来防止多次反序列化后产生多个instance,还有就是防止利用Reflection + setAccessable(true)的单例攻击。
当然这个枚举类在创造实例的时候是threadsafe且是lazy initialized的,因为enum里的枚举值相当于public static final的,Enum实例(INSTANCE)的初始化是在Enum的class被加载时才会发生,而Java只有在Enum类第一次被引用时才会去加载

灵芸 2016-12-27 07:26:45

楼主提出的第一种方法,使用内部类的方式是最佳的方式,也是effective in java推荐的方式。
private static class ManagerHolder { private static final Manager instance = new Manager(); }
虚拟机类加载保证其只被初始化一次。无锁操作。
楼主提出的第二种方法如果getInstance不加锁,则不能保证初始化一次。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文