多线程面试题+答案

线程和进程的区别?

进程:进程独占内存空间,保存各自的运行状态,相互间不干扰且可以互相切换,为并发处理任务提供了可能

线程:共享进程的内存资源,相互间切换更快速,支持更细粒度的任务控制,使进程内的子任务得以并发执行

进程是资源分配的最小单位,线程是CPU调度的最小单位

所有与进程相关的资源,都被记录在PCB中

进程是抢占处理机的调度单位,线程属于进程,共享其资源

线程只由堆栈寄存器,程序计数器和TCB组成

线程不能看做独立应用,而进程可看做独立应用

进程有独立的空间,相互不影响,线程只是进程的不同执行路径

线程没有独立的地址空间,多线程的程序比多线程程序健壮

进程的切换比线程的切换开销大

JAVA中进程与线程的关系

JAVA对操作系统提供的功能进行封装,包括进程和线程

运行一个程序会产生一个进程,进程至少包含一个线程

每个进程对应一个JVM实例,多个线程共享JVM里的堆

JAVA采用单线程编程模型,程序会自动创建主线程

主线程可以创建子线程,原则上要后于子线程完成执行

多线程的优点

发挥多核CPU 的优势

单核 CPU 上所谓的"多线程"是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快

多核CPU上的多线程才是真正的多线程,可以让多段逻辑同时工作,多线程可以真正发挥出多核CPU 的优势

防止阻塞

从程序运行效率的角度来看,单核CPU不会发挥多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。

单核CPU应用多线程是为了防止阻塞【假设:远程读取某个数据,被调用方超时,同时没有设置超时时间,那么整个程序在数据返回之前就停止运行了。多线程可以防止这个问题,多条线程同时运行,如果一条线程的代码执行读取数据阻塞,也不会影响其它任务的执行】

Java实现多线程的方式

1、继承Thread类【Thread本身实现了Runnable接口,当继承Thread类会重写run()方法】

2、实现Runnable接口【实现Runnable接口的run方法,并把Runnable实例传给Thread类;最终调用target.run()方法执行】

总结:

Thread是实现Runnable接口的类,支持多线程

因为类的单一继承原则,推荐使用Runnable接口

错误观点:

1、线程池的本质是提交一个任务,然后在线程池的ThreadFactory中创建一个线程

2、Callable-FutureTask,无返回值是实现Runnable接口,有返回值是实现Callable接口

3、定时器本质是提交一个任务,然后在执行单元中创建一个新的线程

4、Lambda表达式

5、匿名内部类

start()和run()的区别

start方法会创建一个新的子线程并启动

run方法只是Thread的一个普通方法的调用

停止线程的方式

调用interrupt()通知线程中断,而不是强制中断线程

1、如果线程处于被阻塞状态,那么线程将立即退出阻塞状态,并抛出一个interruptedexception异常

2、如果线程处于正常活动状态,那么会将该线程的中断标志设置为true。被设置中断标志的线程将继续正常运行,不受影响

3、需要被调用的线程配合在正常运行任务时,经常检查本线程的中断标志位,如果被设置了中断标志就自行停止线程;

4、如果线程处于正常活动状态,那么会将该线程的中断标志设置为true,被设置中断标志的线程将继续正常运行,不受影响

线程的状态

新建:创建后尚未启动的线程状态

运行(runnable):包含Running和Ready

无限期等待(waiting):不会被分配CPU执行时间,需要显示被唤醒

没有设置timeout参数的OBJECT.wait(0方法

没有设置timeout参数的Thread.join方法

Locksupport.park方法

限期等待(time waiting):在一定时间后会由系统自动唤醒

Thread.sleep方法,

设置了timeout参数的object.wait方法

设置了timeout参数的thread.join方法

Locksupport.parknanos方法

Locksupport.parkuntil方法

阻塞(blocked):等待获取排它锁

结束(Terminated):已终止线程状态,线程已经结束执行

sleep()和wait()的区别?

sleep()是thread类的方法,wait()是Object类中定义的方法

sleep()方法可以在任何地方使用

wait()方法只能在同步锁方法或者同步锁代码块中使用

Thread.sleep()只会让出CPU,不会导致锁行为的改变

Object.wait()不仅让出CPU,还会释放已经占有的同步资源锁

锁池(entrylist):等待释放锁的地方,等锁释放去竞争锁

等待池(waitset)当线程调用某个对象的wait方法,线程就会释放对象的锁,同时线程进入到该对象的等待池中,不会去竞争锁

notify()和notifyA

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

Java之项目解析+八股文 文章被收录于专栏

针对Java简历中项目的功能进行提问,大家可以在评论区中解答/讨论;同时提供八股文

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务