本文共 2816 字,大约阅读时间需要 9 分钟。
一个在深圳从事开发五年的老友一个月前从原公司辞职后,昨天去腾讯总部面试Android高级岗,一面的时候,自我介绍后,陆陆续续问了很多问题,有着五年的从业经验很多项目开发的技术问题都回答的很通顺,面试官也很满意,就在最后以为自己要顺利通过时,【多线程——进程线程】,一个基础问题一时没有答上来就失去了二面的机会!
1.什么是线程
线程就是进程中运行的多个子任务,是操作系统调用的最小单元
2.线程的状态
New:新建状态,new出来,还没有调用start
Runnable:可运行状态,调用start进入可运行状态,可能运行也可能没有运行,取决于操作系统的调度 Blocked:阻塞状态,被锁阻塞,暂时不活动,阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。 Waiting:等待状态,不活动,不运行任何代码,等待线程调度器调度,wait sleep Timed Waiting:超时等待,在指定时间自行返回 Terminated:终止状态,包括正常终止和异常终止
3.线程的创建
a.继承Thread重写run方法
b.实现Runnable重写run方法 c.实现Callable重写call方法 实现Callable和实现Runnable类似,但是功能更强大,具体表现在 a.可以在任务结束后提供一个返回值,Runnable不行 b.call方法可以抛出异常,Runnable的run方法不行 c.可以通过运行Callable得到的Fulture对象监听目标线程调用call方法的结果,得到返回值,(fulture.get(),调用后会阻塞,直到获取到返回值)
4.线程中断
一般情况下,线程不执行完任务不会退出,但是在有些场景下,我们需要手动控制线程中断结束任务,Java中有提供线程中断机制相关的Api,每个线程都一个状态位用于标识当前线程对象是否是中断状态
public boolean isInterrupted() //判断中断标识位是否是true,不会改变标识位public void interrupt() //将中断标识位设置为truepublic static boolean interrupted() //判断当前线程是否被中断,并且该方法调用结束的时候会清空中断标识位 需要注意的是interrupt()方法并不会真的中断线程,它只是将中断标识位设置为true,具体是否要中断由程序来判断,如下,只要线程中断标识位为false,也就是没有中断就一直执行线程方法new Thread(new Runnable(){ while(!Thread.currentThread().isInterrupted()){ //执行线程方法 } }).start(); 前边我们提到了线程的六种状态,New Runnable Blocked Waiting Timed Waiting Terminated,那么在这六种状态下调用线程中断的代码会怎样呢,New和Terminated状态下,线程不会理会线程中断的请求,既不会设置标记位,在Runnable和Blocked状态下调用interrupt会将标志位设置位true,在Waiting和Timed Waiting状态下会发生InterruptedException异常,针对这个异常我们如何处理? 1.在catch语句中通过interrupt设置中断状态,因为发生中断异常时,中断标志位会被复位,我们需要重新将中断标志位设置为true,这样外界可以通过这个状态判断是否需要中断线程try{ .... }catch(InterruptedException e){ Thread.currentThread().interrupt(); } 2.更好的做法是,不捕获异常,直接抛出给调用者处理,这样更灵活
5.Thread为什么不能用stop方法停止线程
从SUN的官方文档可以得知,调用Thread.stop()方法是不安全的,这是因为当调用Thread.stop()方法时,会发生下面两件事:
1.即刻抛出ThreadDeath异常,在线程的run()方法内,任何一点都有可能抛出ThreadDeath Error,包括在catch或finally语句中。 2.释放该线程所持有的所有的锁。调用thread.stop()后导致了该线程所持有的所有锁的突然释放,那么被保护数据就有可能呈现不一致性,其他线程在使用这些被破坏的数据时,有可能导致一些很奇怪的应用程序错误。
6.重入锁与条件对象,同步方法和同步代码块
7.volatile关键字8.java内存模型9.原子性 可见性 有序性10.线程池ThreadPoolExecutor11.线程池的种类12.线程同步机制与原理,举例说明13.arrayList与linkedList的读写时间复杂度14.为什么HashMap线程不安全(hash碰撞与扩容导致)15.进程线程的区别16.Binder的内存拷贝过程17.传统IPC机制的通信原理(2次内存拷贝)18.Java内存模型(记住堆栈是内存分区,不是模型)19.类的加载过程20.什么情况下会触发类的初始化21.双亲委托模式22.双亲委托模式的好处23.死锁的产生条件,如何避免死锁24.App启动流程25.Android单线程模型26.RecyclerView在很多方面能取代ListView,Google为什么没把ListView划上一条过时的横线?27.HashMap如何保证元素均匀分布大家所认知的,给程序员定义的标签一定少不了“宅”这个字,那么 这个宅字我个人所理解的有两层意思,第一就是像很多人所想象的爱宅在家和编程代码过一辈子,第二种呢,就是盲目宅在自己的技术舒适区,眼界不宽,不能看到别人的长处,吸收别人的优点。虽然我不能得知这个宅字是不是真的能运用到所有人身上,但针对我这个老友,他,就是这样。
转载地址:http://xuaga.baihongyu.com/