Java中有那几种引用

https://blog.csdn.net/cselmu9/article/details/51366946

Java中有哪几种引用?它们的含义和区别是什么?

请用Java实现一个线程安全且高效的单例模式。

Java中有哪几种引用?它们的含义和区别是什么?

  • 强引用(Strong Reference),就是我们最常见的普通对象引用。只要还有强引用指向一个对象,就表明对象还“活着”,垃圾收集器就不会碰这种对象。对于一个普通对象,如果没有其他的引用关系,只要超过了引用的作用域或者显示地将相应引用赋值为Null,就可以被垃圾收集了,当然具体回收时机还是要看垃圾收集策略。

  • 软引用(SoftReference),是一种相对于强引用弱化一些的引用,就可以让对象豁免一些垃圾收集,只有当JVM认为内存不足时,才会去试图回收软引用指向的对象。JVM会确保在抛出OutOfMemoryError之前,清理软引用指向的对象。软引用通常用来实现内存敏感的缓存。如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存。

  • 弱引用(WeakReference)并不能使对象豁免垃圾收集,仅仅是提供了一种访问在弱引用状态下对象的途径。这样就可以用来构建一种没有特定约束的关系。如果试图获取的对象还在,就使用它,否则重现实例化。它同样是很多缓存实现的选择。

  • 幻象引用也称之为虚引用,你不能通过它访问对象。虚引用仅仅是一种确保对象被finalize以后,做某些事情的机制,比如,通常用来做所谓的Post-Morterm清理机制。

请用Java实现一个线程安全且高效的单例模式

造成不安全的原因

  • 反射(强行调用私有构造器)
  • 序列化和反序列化
    1)静态内置类实现单例模式
public class MySingleTon {

    public static MySingleTon getInstance() {
        return MySingleHolder.instance;
    }

    private MySingleTon() {
    }

    private static class MySingleHolder {
        private static MySingleTon instance = new MySingleTon();
    }

}

2)双重校验

public class MySingleTon implements Serializable {

    private static final long serialVersionUID = 1L;
    private static volatile MySingleTon instance;

    public static MySingleTon getInstance() {
        if (instance == null) {
            synchronized (MySingleTon.class) {
                if (instance == null) {
                    instance = new MySingleTon();
                }
            }
        }
        return instance;
    }

    private MySingleTon() {
    }

    //反序列化的时候调用
    protected Object readResolve() throws ObjectStreamException {
        return instance;
    }

}

你可能感兴趣的:(Java中有那几种引用)