• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

多线程复习之多线程面试题

技术杂谈 巷子的童年 1个月前 (03-27) 32次浏览 未收录 0个评论 扫描二维码
1. 什么是线程以及进程
进程是指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间)。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。
2. Callable、Runnable的区别
1)Callable可以在任务结束之后提供一个返回值。
2)Callable的call()方法可以抛出异常。
3)运行Callable可以拿到Future对象,Future对象表示异步计算的结果,它提供检查计算是否完成的方法get()。
3.公平锁与非公平锁
 锁分为“公平锁”和“非公平锁”,公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,即FIFO先进先出顺序。而非公平锁就是一种获取锁的抢占机制,是随机获得锁的(允许插队),和公平锁不一样的就是先来的不一定先得到锁,这个方式可能造成某些线程一直拿不到锁,结果也就是不公平的了。通常情况下挂起的线程重新开始与它真正开始运行,之间会产生严重的延时。因此非公平锁就可以利用这段时间完成操作。这是非公平锁在某些时候比公平锁性能要好的原因之一。 
4. notify 和 notifyAll有什么区别
notifyAll()方法(唤醒所有wait 线程并参与竞争)或 notify()方法(只随机唤醒一个 wait 线程参与竞争),当只有一个线程等待时则是一样的。
5. ThreadLocal
ThreadLocal是用来维护线程中的变量不被其他线程干扰而出现的一个结构,内部包含一个ThreadLocalMap类,该类为Thread类的一个局部变量,该Map存储的key为ThreadLocal对象自身,value为我们要存储的对象,这样一来,在不同线程中,持有的其实都是当前线程的变量副本,与其他线程完全隔离,以此来保证线程执行过程中不受其他线程的影响。
6. interrupted 和 isInterrupted
Thread.interrupted()来检查中断状态时,中断状态会被清零。而非静态方法isInterrupted()用来查询其它线程的中断状态且不会改变中断状态标识。
7. fork join框架
Fork/Join框架是Java7提供的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。
工作窃取算法:假如我们需要做一个比较大的任务,我们可以把这个任务分割为若干互不依赖的子任务,为了减少线程间的竞争,于是把这些子任务分别放到不同的队列里,并为每个队列创建一个单独的线程来执行队列里的任务。但是有的线程会先把自己队列里的任务干完,而其他线程对应的队列里还有任务等待处理,干完活的线程就会去其他线程的队列里窃取一个任务来执行。而在这时它们会访问同一个队列,所以为了减少窃取任务线程和被窃取任务线程之间的竞争,通常会使用双端队列,被窃取任务线程永远从双端队列的头部拿任务执行,而窃取任务的线程永远从双端队列的尾部拿任务执行。
8. 进程通信方式
1. 管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。命名管道FIFO,允许无亲缘关系进程间的通信。
2. 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
3. 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,共享内存由一个进程创建,但多个进程都可以访问。
4. 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
5. 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
6. 信号( singal ):信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
9. hashmap线程不安全的例子
1)数据覆盖。如果有A、B两个线程同时对hashMap进行插入操作,刚好插入的数据经过哈希计算后得到的哈希码相同,且该位置还没有其他的数据。假设A在完成hash冲突检测后就把资源让给了线程B,此时B判断该位置没有哈希冲突(线程A的数据还没插入),就完成了数据插入,之后A又得到了资源,将直接在该位置插入而不用再判断。这时候,线程A把线程B插入的数据覆盖了
2)死锁问题。假设有二个进程T1、T2,HashMap容量为2,T1线程放入key A、C、D、E。在T1线程中A、C Hash值相同,于是形成一个链接,假设为A->C,而D、E Hash值不同,于是需要扩容,需要把数据从老的Hash表中迁移到新的Hash表中(refresh)。这时T2进程闯进来了,T1暂时挂起,T2进程也准备放入新的key,这时也发现容量不足,也refresh一把。refresh之后原来的链表结构假设为C->A,之后T1进程继续执行,链接结构为A->C,这时就形成A.next=B,B.next=A的环形链表。一旦取值进入这个环形链表就会陷入死循环。
10. 多线程同步的方法
1)synchronized关键字
2)violatile
3)lock、retrantlock
11. sleep方法与wait方法
1)sleep方法是Thread类的静态方法,它会使线程暂停执行一段时间,等时间到了又会继续执行;wait()是object类中的方法,需要其它线程调用notify()方法唤醒。
2)sleep不释放锁,wait释放锁。
3)wait必须在同步控制方法或者语句块中,sleep不需要。
12.CAP定理
分布式领域CAP理论,Consistency(一致性), 数据一致更新,所有数据变动都是同步的,Availability(可用性), 好的响应性能,Partition tolerance(分区容忍性),可靠性。
13.AQS
AQS是JDK下提供的一个同步框架,实现基于FIFO等待队列的阻塞锁和相关的同步器。这个抽象类被设计为作为一些可用原子int值来表示状态的同步器的基类。AQS管理一个关于状态信息的单一整数,该整数可以表现任何状态。比如, Semaphore 用它来表现剩余的许可数,ReentrantLock 用它来表现拥有它的线程已经请求了多少次锁;FutureTask 用它来表现任务的状态(尚未开始、运行、完成和取消)。

丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:多线程复习之多线程面试题
喜欢 (0)
[247507792@qq.com]
分享 (0)

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00