精选八道多线程面试题,来看看你会几个?

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群

一、多线程有几种实现方案,分别是哪几种?

三种。

1.继承Thread类

2.实现Runnable接口:Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用Runnable接口好了。

3.实现Callable接口。这个得和线程池结合。

二、线程与进程的区别

线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。

不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据

三、什么是线程池? 为什么要使用它?

创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。从JDK1.5开始,Java API提供了Executor框架让你可以创建不同的线程池。比如单线程池,每次处理一个任务;数目固定的线程池或者是缓存线程池(一个适合很多生存期短的任务的程序的可扩展线程池)。

四、同步有几种方式,分别是什么?

两种。

同步代码块

同步方法:

五、启动一个线程是run()还是start()?它们的区别是什么?

启动线程用start();

run(): 封装了被线程执行的代码,直接调用仅仅是普通方法的调用

start(): 启动线程,并由JVM自动调用run()方法

:start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。

六、sleep()和wait()方法的区别

sleep(): 必须指时间; 不释放锁。

wait(): 可以不指定时间,也可以指定时间; 释放锁。

七、为什么wait(),notify(),notifyAll()等方法都定义在Object类中?

因为这些方法的调用是依赖于锁对象的,而同步代码块的锁对象是任意锁。

而Object代码任意的对象,所以,定义在这里面。

线程的生命周期

新建(new):处于该状态的时间很短暂。已被分配了必须的系统资源,并执行了初始化。表示有资格获得CPU时间。调度器可以把该线程变为runnable或者blocked状态

就绪(Runnable):这种状态下只要调度器把时间片分配给线程,线程就能运行。处在这种状态就是可运行可不运行的状态

阻塞(Bolocked):线程能够运行,但有个条件阻止它的运行。当线程处于阻塞状态时,调度器将会忽略线程,不会分配给线程任何CPU时间(例如sleep)。只有重新进入了就绪状态,才有可能执行操作。

死亡(Dead):处于死亡状态的线程讲不再是可调度的,并且再也不会得到CPU时间。任务死亡的通常方式是从run()方法返回。

一个任务进入阻塞状态,可能有如下原因:

1.sleep

2.wait(),知道线程得到了notify()或者notifyAll()消息,线程才会进入就绪状态。

3.任务在等待某个输入/输出完成

4.线程在试图在某个对象上调用其同步控制方法,但是对象锁不可用,因为另一个任务已经获取了这个锁。

八、如何避免死锁?

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。这是一个严重的问题,因为死锁会让你的程序挂起无法完成任务,死锁的发生必须满足以下四个条件:

java技术学习扣qun:59789,1510进群免费送java系统学习视频!

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

好了,本篇文章就分享到这里了。有兴趣的新手伙伴们可以关注收藏起来,以后需要的时候可以多看看。如果有正在学java的程序员,可来我们的java技术学习扣qun哦:59789,1510里面免费送java的视频系统教程!

猜你喜欢

转载自blog.csdn.net/weixin_43660525/article/details/85636764