java单例基础_Java基础知识(引用,单例)

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

强引用

只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象

Obejct obj = new Object();

obj = null;//强行中断引用可以赋值为Null

复制代码软引用(SoftReference)

有用但是不必须对象 , 只有在内存不足的时候JVM才会回收该对象

Object obj = new Object();

SoftReference sr = new SoftReference<>(obj);

Object obj2 = sr .get();

复制代码弱引用(WeakReference)

当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象

Object obj = new Object();

WeakReference wr= new WeakReference<>(obj);

wr.get();

复制代码虚引用(PhantomReference)

虚引用不会决定对象的生命周期,如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。

虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是 否已经加入了虚引用,来了解

被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

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

1.静态内部类

public class A {

public A(){

}

public A getInstance(){

return B.sInstance;

}

private static class B{

private static final A sInstance = new A();

}

}

复制代码

利用类加载机制来保证只创建一个Instance实例,只要应用中不使用内部类,JVM就不会去加载这个单例类,也就不会去创建单例对象

不安全的地方:

(1) 可以被反射强行调用私有构造器

(2) 需要额外的工作来实现序列化,否则反序列化的时候,都会创建新的实例

静态内部类实现线程安全的原因:

内部类加载时机是在类被调用的时候,也就是A.getInstance(),B才会加载,属于延迟加载

static 对象具有唯一性,只会在类加载的时候初始化一次

2.双重锁定检查(DCL)

public class A implements Serializable {

private A(){

}

private static volatile A sInstance ;

public static A getInstance(){

if (sInstance != null){

synchronized (A.this){

if (sInstance != null){

sInstance = new A();

}

}

}

return sInstance;

}

//序列化安全

private Object readResolve(){

return sInstance;

}

}

复制代码

防止序列化,消除指令重排对单例的影响

3、为什么Java内部类要设计成静态和非静态两种。

根据Oracle官方的说法:Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.

从字面上看,一个被称为静态嵌套类,一个被称为内部类。

什么是嵌套?嵌套就是我跟你没关系,自己可以完全独立存在,但是我就想借你的壳用一下,来隐藏一下我自己。

什么是内部?内部就是我是你的一部分,我了解你,我知道你的全部,没有你就没有我。(所以内部类对象是以外部类对象存在为前提的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值