Java面试题讲解总结——第五回(据说是华为大佬讲的)

十七、Java中的异常体系

Java中所有异常都来自顶级父类Throwable;

Throwable下有两个子类,Exception和Error;

Error是程序无法处理的错误,一旦发生将导致程序被迫停止;

Exception一般不会导致程序停止,又分为RuntimeException发生在程序运行时,会导致当前线程运行失败,而CheckedException发生在程序编译时,会导致当前程序编译不通过。

十八、GC如何判断对象可以被回收

引用计数法(Java中没有使用):每个对象有一个计数属性,每增加一个引用计数+1,每减少一个引用计数-1,当计数为0是则该对象可以被回收;缺点:当出现对象互相引用时,就算它们都不被使用时因计数为1而无法被回收。

可达性分析(Java中使用):从GC Roots向下搜索,搜索走过的路径成为引用链,当一个对象到GC Roots没有任何一条引用链可达时,则说明该对象是不可用的,虚拟机可以回收。

可以作为GC Roots的有:

1. 虚拟机栈(栈帧中变量表)中引用的对象;

2. 方法区中类静态属性引用的对象;

3. 方法区中常量引用的对象;

4. 本地方法中JNI(即一般说的native方法)引用的对象。

可达性分析失败之后不一定被立即回收,在确定死透之前可能会经历两个过程:

1. 没有找到可达的引用链;

2. 查看对象是否重写了每个对象只能调用一次的finalize()方法,如果有那么还可以在抢救一下如重新建立链接如果失败则彻底死透回收,如果没有调用过则放到F-Queue队列中等待,但也不承诺一定执行。

十九、 线程的生命周期及线程有哪些状态?

1. 线程通常有5种状态:创建、就绪、运行、阻塞、死亡;

2. 阻塞分为三种:

(1) 等待阻塞:当运行中的线程调用wait()时,该线程会释放其所有资源,JVM会将这个线程放入等待池,该线程不能自动唤醒,只能由其他线程调用Notify或NotifyAll唤醒,wait()是Object类方法;

(2) 同步阻塞:运行的线程在获取对象同步锁时,该同步锁被别的线程占用,则当前线程被JVM放入锁池;

(3) 其他阻塞:运行的线程执行了sleep或者join方法,或发出了I/O申请,JVM 都会将该程序置为阻塞状态,当sleep状态超时、join等待线程结束或超时、或I/O处理完毕,线程重新转入就绪状态。sleep是Thread类方法。

创建(new):创建一个新的线程;

就绪(Runnable):线程创建后,其他线程调用了该线程的start方法,该线程被放入可运行线程池,变得可运行了,等待获取CPU使用权;

运行(Running):就绪状态的线程获取到CPU,运行程序;

阻塞(Blocked):线程因某种原因放弃CPU使用权,暂时停止运行,直到转为就绪状态后才有机会继续运行;

死亡(Dead):线程执行完毕或因某种原因退出run方法,该线程生命周期结束。

二十、sleep()、join()、wait()、yield()的区别?

1.锁池

所有需要竞争同步锁的线程都会放在锁池当中,比如当前对象的锁已经被其中一个线程得到,则其他线程需要在这个锁池进行等待,当前面的线程释放同步锁后锁池中的线程去竞争同步锁,当某个线程得到后会进入就绪队列进行等待cpu资源分配。

2.等待池

当我们调用wait()方法后,线程会放到等待池当中,等待池的线程是不会去竞争同步锁。只有调用了notify()或notifyAll()后等待池的线程才会开始去竞争锁,notify()是随机从等待池选出一个线程放到锁池,而notifyAll()是将等待池的所有线程放到锁池当中

1. sleep 是 Thread 类的静态本地方法,wait 则是 Object 类的本地方法。

2. sleep 就是把CPU的执行资格和执行权释放出去,不再运行此线程,当定时时间结束再取回CPU资源,参与CPU的调度,获取到CPU资源后就可以继续运行了。而如果sleep时该线程有锁,那么sleep不会释放这个锁,而是把锁带着进入了冻结状态,也就是说其他需要这个锁的线程根本不可能获取到这个锁。也就是说无法执行程序。如果在睡眠期间其他线程调用了这个线程的interrupt方法,那么这个线程也会抛出interruptexception异常返回,这点和wait是一样的。

3. sleep不依赖于同步器synchronized,但是wait依赖于synchronized。

4. sleep不需要被唤醒,到时间自动退出阻塞,而wait方法需要。

5. sleep一般用于当前线程的休眠或暂停,而wait则是用于多线程之间的通讯。

6. sleep会主动让出CPU之后强制切换上下文,而wait后还有可能竞争到锁重新执行,不一定切换上下文。

7. yield:使当前正在执行的线程向另一个线程交出运行权。注意这是一个静态方法。
该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield方法只能让同优先级的线程有执行的机会。
(1) yield执行后线程直接进入就绪状态。
(2) yield会释放cpu资源,但是不会释放同步锁(类锁和对象锁)

8. join:执行后线程进入阻塞状态,例如在线程B中调用线程A的join,那线程B会进入到阻塞队列,直到线程A结束或中断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值