【Android面试】Java面试题整合(二)
一、线程池是干嘛的,优点有哪些?
线程池主要用作管理子线程,优点有:重用线程池中的线程,避免频繁创建和销毁线程所带来的内存开销。 有效控制线程的最大并发数,避免因线程之间抢占资源而导致的阻塞现象。能够对线程进行简单的管理,提供定时执行以及指定时间间隔循环执行等功能。
二、线程池的构造方法每个参数是什么意思,执行任务的流程。
1、corePoolSize:核心线程数。默认情况下线程池是空的,只是任务提交时才会创建线程。如果当前运行的线程数 少于corePoolSize,则会创建新线程来处理任务;如果等于或者等于corePoolSize,则不再创建。如果调用线程池 的prestartAllcoreThread方法,线程池会提前创建并启动所有的核心线程来等待任务。
2、 maximumPoolSize:线程池允许创建的最大线程数。如果任务队列满了并且线程数小于maximumPoolSize时, 则线程池仍然会创建新的线程来处理任务。
3、keepAliveTime:非核心线程闲置的超时事件。超过这个事件则回收。如果任务很多,并且每个任务的执行时间 很短,则可以调大keepAliveTime来提高线程的利用率。另外,如果设置allowCoreThreadTimeOut属性来true 时,keepAliveTime也会应用到核心线程上。
4、TimeUnit:keepAliveTime参数的时间单位。可选的单位有天Days、小时HOURS、分钟MINUTES、秒 SECONDS、毫秒MILLISECONDS等。
5、workQueue:任务队列。如果当前线程数大于corePoolSzie,则将任务添加到此任务队列中。该任务队列是 BlockingQueue类型的,即阻塞队列。
6、ThreadFactory:线程工厂。可以使用线程工厂给每个创建出来的线程设置名字。一般情况下无须设置该参数。 RejectedExecutionHandler:拒绝策略。这是当前任务队列和线程池都满了时所采取的应对策略,默认是 AbordPolicy,表示无法处理新任务,并抛出RejectedExecutionException异常。
执行任务流程:
如果线程池中的线程数量未达到核心线程的数量,会直接启动一个核心线程来执行任务。 如果线程池中的线程数量已经达到或者超过核心线程的数量,那么任务会被插入到任务队列中排队等待执行。 如果任务队列无法插入新任务,说明任务队列已满,如果未达到规定的最大线程数量,则启动一个非核心线程来 执行任务。 如果线程数量超过规定的最大值,则执行拒绝策略-RejectedExecutionHandler。
三、什么是泛型?
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类 型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参 数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
四、final、finally、finalize 的区别
final:在java中,final可以用来修饰类,方法和变量(成员变量或局部变量)。当用final修饰类的时,表明该类不能被其他类所继承。当我们需要让一个类永远不被继承,此时就可以用final修饰,但要注意:final类中所有的成员方法都会隐式的定义为final方法。
finally:finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下。
#android面试#finalize:finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般是不需要程序员去实现finalize的。 特殊情况下,需要程序员实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。 使用finalize还需要注意一个事,调用super.finalize();