Android面试题线程篇,由本人整理汇总,后续将推出系列篇,如果喜欢请持续关注和推荐。

开启线程的三种方式?

java有三种创建线程的方式,分别是继承Thread类、实现Runable接口和使用线程池

线程池:

Android中常见的线程池有四种,FixedThreadPool、CachedThreadPool、ScheduledThreadPool、SingleThreadExecutor。

  • FixedThreadPool线程池是通过Executors的new FixedThreadPool方法来创建。它的特点是该线程池中的线程数量是固定的。即使线程处于闲置的状态,它们也不会被回收,除非线程池被关闭。当所有的线程都处于活跃状态的时候,新任务就处于队列中等待线程来处理。注意,FixedThreadPool只有核心线程,没有非核心线程。
  • CachedThreadPool线程池是通过Executors的newCachedThreadPool进行创建的。它是一种线程数目不固定的线程池,它没有核心线程,只有非核心线程,当线程池中的线程都处于活跃状态,就会创建新的线程来处理新的任务。否则就会利用闲置的线程来处理新的任务。线程池中的线程都有超时机制,这个超时机制时长是60s,超过这个时间,闲置的线程就会被回收。这种线程池适合处理大量并且耗时较少的任务。这里得说一下,CachedThreadPool的任务队列,基本都是空的。
  • ScheduledThreadPool线程池是通过Executors的newScheduledThreadPool进行创建的,它的核心线程是固定的,但是非核心线程数是不固定的,并且当非核心线程一处于空闲状态,就立即被回收。这种线程适合执行定时任务和具有固定周期的重复任务。
  • SingleThreadExecutor线程池是通过Executors的newSingleThreadExecutor方法来创建的,这类线程池中只有一个核心线程,也没有非核心线程,这就确保了所有任务能够在同一个线程并且按照顺序来执行,这样就不需要考虑线程同步的问题。

sleep(), wait()的区别

  • sleep不释放同步锁,自动唤醒,需要try catch, wait释放同步锁,需要notify来唤醒
  • sleep是线程的方法 wait是Object的方法

谈谈wait/notify关键字的理解

等待对象的同步锁,需要获得该对象的同步锁才可以调用这个方法,否则编译可以通过,但运行时会收到一个异常:IllegalMonitorStateException。

调用任意对象的 wait() 方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被释放。

唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个在等待),注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。

调用任意对象的notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。

Thread中的start()和run()方法有什么区别

start()方法是用来启动新创建的线程,而start()内部调用了run()方法,这和直接调用run()方法是不一样的,如果直接调用run()方法,

如何控制某个方法允许并发访问线程的个数?

  • semaphore.acquire() 请求一个信号量,这时候的信号量个数-1(一旦没有可使用的信号量,也即信号量个数变为负数时,再次请求的时候就会阻塞,直到其他线程释放了信号量)
  • semaphore.release() 释放一个信号量,此时信号量个数+1

什么导致线程阻塞?线程如何关闭?

阻塞式方法是指程序会一直等待该方法完成期间不做其他事情,ServerSocket的accept()方法就是一直等待客户端连接。这里的阻塞是指调用结果返回之前,当前线程会被挂起,直到得到结果之后才会返回。此外,还有异步和非阻塞式方法在任务完成前就返回。

一种是调用它里面的stop()方法

另一种就是你自己设置一个停止线程的标记 (推荐这种)

如何保证线程安全?

  • 1.synchronized;
  • 2.Object方法中的wait,notify;
  • 3.ThreadLocal机制 来实现的。

如何实现线程同步?

  • 1、synchronized关键字修改的方法。
  • 2、synchronized关键字修饰的语句块
  • 3、使用特殊域变量(volatile)实现线程同步

线程间操作List

List list = Collections.synchronizedList(new ArrayList());

谈谈对Synchronized关键字,类锁,方法锁,重入锁的理解

java的对象锁和类锁:java的对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的,对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的class对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的

synchronized 和volatile 关键字的区别

  • 1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
  • 2.volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
  • 3.volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
  • 4.volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
  • 5.volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化

ReentrantLock 、synchronized和volatile比较

java在过去很长一段时间只能通过synchronized关键字来实现互斥,它有一些缺点。比如你不能扩展锁之外的方法或者块边界,尝试获取锁时不能中途取消等。Java 5 通过Lock接口提供了更复杂的控制来解决这些问题。 ReentrantLock 类实现了 Lock,它拥有与 synchronized 相同的并发性和内存语义且它还具有可扩展性。

线程同步的问题,常用的线程同步

  • 1.sycn:保证了原子性、可见性、有序性
  • 2.锁:保证了原子性、可见性、有序性
    • 1.自旋锁:可以使线程在没有取得锁的时候,不被挂起,而转去执行一个空循环。
    • 1.优点:线程被挂起的几率减少,线程执行的连贯性加强。用于对于锁竞争不是很激烈,锁占用时间很短的并发线程。
    • 2.缺点:过多浪费CPU时间,有一个线程连续两次试图获得自旋锁引起死锁
    • 2.阻塞锁:没得到锁的线程等待或者挂起,Sycn、Lock
    • 3.可重入锁:一个线程可多次获取该锁,Sycn、Lock
    • 4.悲观锁:每次去拿数据的时候都认为别人会修改,所以会阻塞全部其他线程 Sycn、Lock
    • 5.乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。cas
    • 6.显示锁和内置锁:显示锁用Lock来定义、内置锁用synchronized。
    • 7.读-写锁:为了提高性能,Java提供了读
  • 3.volatile
    • 1.只能保证可见性,不能保证原子性
    • 2.自增操作有三步,此时多线程写会出现问题
  • 4.cas
    • 1.操作:内存值V、旧的预期值A、要修改的值B,当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做并返回false。
    • 2.解释:本地副本为A,共享内存为V,线程A要把V修改成B。某个时刻线程A要把V修改成B,如果A和V不同那么就表示有其他线程在修改V,此时就表示修改失败,否则表示没有其他线程修改,那么把V改成B。
    • 3.局限:如果V被修改成V1然后又被改成V,此时cas识别不出变化,还是认为没有其他线程在修改V,此时就会有问题
    • 4.局限解决:将V带上版本。
  • 5.线程不安全到底是怎么回事:
    • 1.一个线程写,多个线程读的时候,会造成写了一半就去读
    • 2.多线程写,会造成脏数据

有三个线程T1,T2,T3,怎么确保它们按顺序执行?

在多线程中有多种方法让线程按特定顺序执行,你可以用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。为了确保三个线程的顺序你应该先启动最后一个(T3调用T2,T2调用T1),这样T1就会先完成而T3最后完成。

Android的多线程模型有哪几种?

Android提供了四种常用的操作多线程的方式,分别是:

  1. Handler+Thread
  2. AsyncTask
  3. ThreadPoolExecutor
  4. IntentService

Android多线程的实现方式有哪些?

  • Thread & AsyncTask
  • Thread 可以与Loop 和 Handler 共用建立消息处理队列
  • AsyncTask 可以作为线程池并行处理多任务

多线程的优劣

使用多进程显而易见的好处就是分担主进程的内存压力。我们的应用越做越大,内存越来越多,将一些独立的组件放到不同的进程,它就不占用主进程的内存空间了。当然还有其他好处,有心人会发现Android后台进程里有很多应用是多个进程的,因为它们要常驻后台,特别是即时通讯或者社交应用,不过现在多进程已经被用烂了。典型用法是在启动一个不可见的轻量级私有进程,在后台收发消息,或者做一些耗时的事情,或者开机启动这个进程,然后做监听等。还有就是防止主进程被杀守护进程,守护进程和主进程之间相互监视,有一方被杀就重新启动它。 坏处的话,多占用了系统的空间,大家都这么用的话系统内存很容易占满而导致卡顿。消耗用户的电量。应用程序架构会变复杂,应为要处理多进程之间的通信。这里又是另外一个问题了。

AsyncTask的工作原理

AsyncTask是Android本身提供的一种轻量级的异步任务类。它可以在线程池中执行后台任务,然后把执行的进度和最终的结果传递给主线程更新UI。实际上,AsyncTask内部是封装了Thread和Handler。虽然AsyncTask很方便的执行后台任务,以及在主线程上更新UI,但是,AsyncTask并不合适进行特别耗时的后台操作,对于特别耗时的任务,个人还是建议使用线程池。

HandlerThread是什么

MessageQueue + Looper + Handler

IntentService是什么

含有HandlerThread的Service,可以多次startService()来多次在子线程中进行 onHandlerIntent()的调用。

线程间如何通信

我们知道线程是CPU调度的最小单位。在Android中主线程是不能够做耗时操作的,子线程是不能够更新UI的。而线程间通信的方式有很多,比如广播,Eventbus,接口回掉,在Android中主要是使用handler。handler通过调用sendmessage方法,将保存消息的Message发送到Messagequeue中,而looper对象不断的调用loop方法,从messageueue中取出message,交给handler处理,从而完成线程间通信。

如果喜欢本文章,请关注Android高级编程微信公众号,有更多精彩内容提供:

Android面试题线程篇相关推荐

  1. Android面试题算法篇

    Android面试题算法篇,由本人整理汇总,后续将继续推出系列篇,如果喜欢请持续关注和推荐,更多精彩内容可以关注微信公众号(Android高级编程):android-tech 系列文章目录: Andr ...

  2. Android面试题网络篇

    Android面试题网络篇,由本人整理汇总,后续将继续推出系列篇,如果喜欢请持续关注和推荐. 系列文章目录: Android面试题View篇 Android面试题进程篇 Android面试题线程篇 T ...

  3. Android面试题Java基础篇

    Android面试题Java基础篇,由本人整理汇总,后续将继续推出系列篇,如果喜欢请持续关注和推荐,更多精彩内容可以关注微信公众号(Android高级编程):android-tech 系列文章目录: ...

  4. Android面试题数据结构篇

    Android面试题数据结构篇,由本人整理汇总,后续将继续推出系列篇,如果喜欢请持续关注和推荐,更多精彩内容可以关注微信公众号(Android高级编程):android-tech 系列文章目录: An ...

  5. Android面试题整理(源自鸿洋大神公众号【201803】的一篇BAT面试题推送)

    三月,想必各位程序员GG 此刻想要的,莫过于一篇面试宝典.鄙人不才,也从未系统的刷过面试题,以鸿洋大哥一篇面试题为引,略加整理,希望能帮到各位不知道看什么小伙伴.(大部分知识都是有答案的). 原文链接 ...

  6. 2018年Android面试题整理

    这是我近段时间收集的面试题,献给打算年后找工作的同学们.文中涉及的知识比较广也可能比较零散,并且一些较为基础的知识我都略去了(比如Android四大组件是什么这类问题),有些我附上了自己的理解,有些附 ...

  7. 2020年度整理国内一线互联网公司内部Android面试题库

    一眨眼又到年底了,每到这个时候,我们都会慢慢反思,这一年都做了什么?有什么进步?年初的计划都实现了吗?明年年初有跳槽的底气了吗? 况且2020年我们经历了新冠疫情的洗礼,很多程序员都经历了失业,找工作 ...

  8. 2017常见android面试题

    介绍自己负责的部分,如何实现的. 框架的搭建 排查问题以及结解决方式 兼容性保证 性能优化 上线之后模块导致crash的比例 自定义view viewGroup 这个就是约定的几个方法,onMeasu ...

  9. Android面试题集1

    1. 什么是Activity? 四大组件之一,一般的,一个用户交互界面对应一个activity setContentView() ,// 要显示的布局 , activity 是Context的子类,同 ...

最新文章

  1. STM32迷你板UCOSII系统移植
  2. python获取指定目录下所有文件名os.walk和os.listdir
  3. Mybatis mapper代理Dao开发
  4. python断点调试出现问题_Python错误、调试
  5. python中的引用,Python里的引用和拷贝
  6. LeetCode113. 路径总和||
  7. linux删除指定大小的文件,Linux 脚本删除大于指定大小的文件
  8. php mysql join查询结果_PHP mySQL表JOIN查询 - 最有效的方法?
  9. N8变砖后的强刷方法
  10. Windows+WSL+DockerDesktop下安装OpenV2X
  11. 李沐动手学深度学习v2/总结3
  12. 鸿蒙系统用的什么代码,鸿蒙系统是用什么语言开发的?
  13. html显示在最上,让DIV对象显示在最上层
  14. WeChat苹果多开系统官网下载页源码
  15. 一个直播源码搭建教程,教你如何完成一个完整的直播
  16. 笔记本自带键盘的关闭和开启
  17. 迪克体育Dick’s Sporting Goods EDI需求分析
  18. AppWidgetService创建报错java.lang.StackOverflowError: stack size 8MB
  19. 安全生产精细化管理规划
  20. 【原创作品】爱博QQ邮件搜索机 注册机 增强补丁V2.2 (包括试用版邮箱导出补丁) 支持最新版本的 Ver 2.5.2 Build 036

热门文章

  1. RobotStudio软件:机器人仿真视频录制功能使用方法
  2. undeclared name问题,一定要仔细啊
  3. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第30讲:PHP多维数组
  4. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第十讲:深入理解盒子模型
  5. stm32驱动 ov7670发送到串口上位机显示图像
  6. android开发笔记之Makefile(一)
  7. 龙傲天程序员之路 其一
  8. jython_Jython简介,第2部分:编程要点
  9. 8051单片机c语言编程模板,完美的8051单片机C语言编程模板.doc
  10. Java开发环境配置“IntelliJ IDEA”,超详细整理,适合新手入门