2019Android多线程面试题总结

640?wx_fmt=gif

640?wx_fmt=gif

极力推荐文章:欢迎收藏

Android 干货分享 640?wx_fmt=gif

和您一起终身学习,这里是程序员Android

1.什么是线程

线程就是进程中运行的多个子任务,是操作系统调用的最小单元

2.线程的状态

1.New:

新建状态,new出来,还没有调用start

2.Runnable:

可运行状态,调用start进入可运行状态,可能运行也可能没有运行,取决于操作系统的调度

3.Blocked:

阻塞状态,被锁阻塞,暂时不活动,阻塞状态是线程阻塞在进入

4.synchronized:

关键字修饰的方法或代码块(获取锁)时的状态。

5.Waiting:

等待状态,不活动,不运行任何代码,等待线程调度器调度,waitsleep用来暂停当前线程的执行,以毫秒为单位,任何其它线程都可以中断当前线程的睡眠,这种情况下将抛出InterruptedException异常

6.Timed Waiting:

超时等待,在指定时间自行返回

7.Terminated:

终止状态,包括正常终止和异常终止

3.线程的创建

线程创建的常用方法
  • 1.继承Thread重写run方法

  • 2.实现Runnable重写run方法

  • 3.实现Callable重写call方法

实现Callable重写call方法

实现Callable和实现Runnable类似,但是功能更强大,具体表现在

  • a.可以在任务结束后提供一个返回值,Runnable不行

  • b.call方法可以抛出异常,Runnablerun方法不行

  • c.可以通过运行Callable得到的Fulture对象监听目标线程调用call方法的结果,得到返回值,(fulture.get(),调用后会阻塞,直到获取到返回值)

4.线程中断

一般情况下,线程不执行完任务不会退出,但是在有些场景下,我们需要手动控制线程中断结束任务,Java中有提供线程中断机制相关的Api,每个线程都一个状态位用于标识当前线程对象是否是中断状态


public boolean isInterrupted() //判断中断标识位是否是true,不会改变标识位
public void interrupt()  //将中断标识位设置为true
public static boolean interrupted() //判断当前线程是否被中断,并且该方法调用结束的时候会清空中断标识位

需要注意的是interrupt()方法并不会真的中断线程,它只是将中断标识位设置为true,具体是否要中断由程序来判断,如下,只要线程中断标识位为false,也就是没有中断就一直执行线程方法

new Thread(new Runnable(){
      while(!Thread.currentThread().isInterrupted()){
              //执行线程方法
      }
}).start();

前边我们提到了线程的六种状态,New 、Runnable、 Blocked、 Waiting、 Timed Waiting、 Terminated,那么在这六种状态下调用线程中断的代码会怎样呢,NewTerminated状态下,线程不会理会线程中断的请求,既不会设置标记位,在RunnableBlocked状态下调用interrupt会将标志位设置位true,在WaitingTimed 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,包括在catchfinally语句中。

  • 2.释放该线程所持有的所有的锁。调用thread.stop()后导致了该线程所持有的所有锁的突然释放,那么被保护数据就有可能呈现不一致性,其他线程在使用这些被破坏的数据时,有可能导致一些很奇怪的应用程序错误。

6.同步方法和同步代码块

为何要使用同步?java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用,从而保证了该变量的唯一性和准确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员Android

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值