多线程相关面试题及其解答

Q:什么是线程?什么是进程?线程和进程有什么区别?

A:线程:又称"轻量级进程",是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程中的实际运作单位。

进程: 系统进行资源分配和调度的基本单位。

两者之间的区别:
地址空间和其他资源:进程间相互独立,同一进程的各线程间共享,某进程中的线程在其他进程不可见。
通信:进程间通信 IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
调度和切换:线程上下文切换比进程上下文切换要快得多。
在多线程 OS 中,进程不是一个可执行的实体。


Q:多线程编程的好处是什么?

A:发挥多核 CPU 的优势(提高性能)、防止阻塞、便于建模


Q:有几种创建线程的方式?哪种比较好?

A:①、实现 Runnable 接口(较好:灵活,减少耦合度);②、继承 Thread 类。


Q:Runnable 接口和 Callable 接口的区别?

A:Callable 接口中的 call() 方法是可以返回值和抛出异常,是一个泛型,和 Future / FutureTask 配合来获取结果。而 Runnalbe 接口的 run() 方法,无返回值。


Q:Java 中 CyclicBarrier 和 CountDownLatch 有什么不同?

A:①、CyclicBarrier 是 n 个线程,相互等待;CountDownLatch 是一个或多个线程,等待另外 n 个线程执行完,再执行。
②、CyclicBarrier 计数;CountDownLatch 计数。
③、CyclicBarrier 计数达到指定值时,计数置为 0 重新开始;CountDownLatch 计数为 0 时,无法重置。(不可重复利用
④、CyclicBarrier 调用 await() 方法计数加 1 , 若加 1 后的值不等于构造方法的值,则线程阻塞;CountDownLatch 调用 countDown() 方法计数减 1 ,调用 await() 方法只进行阻塞,对计数没任何影响。


Q:volatile 是什么?作用是什么?

A:volatile 是一个类型修饰符,是用来修饰被不同线程访问和修改的变量

主要作用有两个:①、内存可见性,即线程 A 对 volatile 变量的修改,其他线程获取的 volatile 变量都是最新的;②、可以禁止指令(程序执行的顺序)重排序


Q:什么是线程安全?

A:线程安全:多线程访问时,采用了加锁机制,当一个数据访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
线程不安全不提供数据访问保护,有可能多个线程先后更改数据造成所得到的数据是脏数据


Q:线程安全分为哪几种级别?

A:①、不可变不变的对象绝对是线程安全的,不需要线程同步,如 String、Long、BigInteger;
②、无条件的线程安全:对象自身做了足够多的内部同步,也不需要外部同步,如 Random、ConcurrentHahsMap、Concurrent 集合、atomic;
③、有条件的线程安全:对象的部分方法可以无条件安全使用,但是有些地方需要外部同步,需要 Collectiongs.synchronized;有条件线程安全的最常见的例子是遍历由 HashTable 或者 Vector 或者返回的迭代器;
④、非线程安全(线程兼容):对象本身不提供线程安全机制,但是通过外部同步,可以在并发环境使用,如 ArrayList、HashMap;
⑤、线程对立:即使外部进行了同步调用,也不能保证线程安全,这种情况非常少,如 System.setOut()、System.runFinalizersOnExit()。


Q:如何正确地停止一个线程?

A:①、使用退出标志,使线程正常退出,也就是当 run 方法完成后线程终止;
②、使用 interrupt 方法中断线程
③、使用 stop 方法强行终止,但是不推荐使用,因为 stop 和 suspend 以及 resume 一样存在死锁威胁,并且都是过期作废的方法。


Q:一个线程运行时发生异常会怎样?

A:①、如果异常没有被捕获,该线程将会停止执行
②、如果这个线程持有某个对象的监视器,那么这个对象监视器会被立即释放


Q:两个线程之间,如何实现数据共享?

A:①、使用同一个 Runnable 对象;
②、使用不同的 Runnable 对象:
i、将共享数据分别传递给两个不同的线程
ii、将这些 Runnable 对象作为一个内部类,将共享数据作为成员变量


Q:sleep() 方法和 wait() 方法有什么区别?

A:①、所在的类:sleep 在 Thread 类中、wait 在 Object 类中;
②、锁:sleep 方法没有释放锁、wait 方法释放了锁
③、使用范围:sleep 可以在任何地方使用、而 wait,notify 和 notifyAll 只能在同步控制方法或者同步控制块里面使用


Q:ThreadLoacl 是什么?作用是什么?

A:它是线程局部变量,每个线程都有自己的 ThreadLocal。

作用:把数据进行隔离,数据不共享(空间换时间,在 Thread 中维护了一个以开地址法实现的 ThreadLocalMap )。


Q:为什么 wait() 方法和 notify()/notifyAll() 方法要在同步块( synchronized )中被调用?

A:JDK 强制的,方法调用之前必须先获得对象的锁。如果不这样做,就会抛出 IllegalMonitorStateException 异常。


Q:同步集合 & 并发集合的区别?

A:都支持线程安全,主要区别体现在性能可扩展性

性能:同步集合会把整个 Map 或者 List 锁起来,而并发集合不会。所以同步集合比并发集合慢的多。
可扩展性并发集合不仅提供线程安全,还用锁分离和内部分区等现代技术来提高可扩展性。


Q:什么是线程池? 为什么要使用它?

A:在程序启动时,就创建若干个线程来响应请求。使用它,可以避免频繁地创建和销毁线程,达到线程对象的重用,还可以根据项目灵活地控制并发的数目


Q:什么是死锁?死锁发生的必要条件?如何避免死锁?

A:死锁:两个及以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,他们都将无法推进下去。

死锁的必要条件
①、互斥条件:一个资源每次只能被一个进程使用;
②、请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不变;
③、不剥夺条件:进程已获得的资源,在未使用之前,不能强行剥夺;
④、循环等待条件:若干进程之间形成一种头尾相连的循环等待资源关系。

避免死锁最简单的方法阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序做操作。


Q:活锁 & 死锁的区别?

A:活锁进程的状态可以改变但是却不能继续执行


Q:怎么检测一个线程是否拥有锁?

A:Thread 中的 holdsLock() 方法:如果当且仅当当前线程拥有某个具体对象的锁时,返回 true


Q:synchronized & ReentrantLock 的区别?

A:两者都是加锁方式同步(阻塞式同步)

其本质上的区别:synchronized 是关键字,ReentrantLock 是类。
相对于 synchronized 而言,ReentrantLock 类提供了一些高级功能:
①、等待可中断:持有锁的线程长期不释放时,正在等待的线程可以选择放弃等待,这相等于 synchronized 来说,避免了死锁
②、公平锁:synchronized 只能是非公平锁,ReenTrantLock 可以通过构造函数的参数来指定公平锁和非公平锁。(公平锁:先等待的线程先得到锁);
③、锁绑定多个条件:一个 ReentrantLock 对象可以同时绑定多个对象。
④、锁机制不一样:synchronized


Q:如何保证线程按照指定顺序执行?

A:使用 new Thread().join() 方法:等待线程结束。也就是说通过一个线程等待另一个线程执行完毕,再继续执行,来实现。


Q:如果你提交任务时,线程池队列已满。会时发会生什么?

A:当一个任务不能被调度执行时,ThreadPoolExecutor 的 submit() 方法将会抛出 RejectedExecutionException 异常。


Q:Java 线程池中 submit() & execute() 方法有什么区别?

A:①、接收的参数不一样;②、submit() 有返回值,execute() 没有
;③、submit() 方便 Exception 处理


Q:ReadWriteLock 是什么?

A:维护一对关联的锁,一个用于只读操作,一个用于写操作读锁是共享的,而写锁是独占的。


Q:多线程中的忙循环是什么?使用它的目的是什么?

A:忙循环:用循环让一个线程等待,不会放弃 CPU

目的:为了保留 CPU 缓存,避免重建缓存和减少等待重建时间。在多核系统中,一个等待线程醒来时,可能会在另一个内核运行,这样就会重建缓存。


Q:遵循的多线程的最佳实践有哪几条?

A:①、给线程起一个有意义的名字;②、避免锁定和缩小同步的范围;③、多用同步类,少用 wait 和 notify;④、多用并发集合,少用同步集合。


Q:如何强制启动一个线程?

A:它是被线程调度器控制的,并且 Java 没有公布相关的 API。


Q:fork-join 框架是什么?

A:Java7 提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。使用了工作窃取算法

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容