Java面试题2020 -- 多线程
多线程常见面试题
1 Java中线程定义 :
线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对 运算密集型任务提速 .
2 线程的生命周期
2.1 阻塞状态:
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或者获得设备资源之后可以重新进入就绪状态。
可以分为三种:
等待阻塞:运行状态中的线程执行wait()方法,使线程进入到等待阻塞状态。
同步阻塞:线程在获取synchronized同步锁失败(因为同步锁被其他线程占用)。
其他阻塞:通过调用线程的sleep()或者join()发出I/O请求时,线程就会进入到阻塞状态。
当sleep()状态超时,join()等待线程终止或者超时,或者I/O处理完毕,线程重新转入就绪状态。
3 多线程的实现方式
1 继承Thread 类 ,重写run方法(其实Thread类本身也实现了Runnable接口)
2 实现Runnable接口,重写run方法
3 实现Callable接口,重写call方法(有返回值)
4 使用线程池(有返回值)
4 Runnable 和 Thread区别
Java 是单继承 ,可多实现 , 若存在继承其他的类, 考虑实现Runnable接口
5 start() 和 run() 方法有什么区别
start()方法被用来启动新创建的线程,而且start()内部 调用了run()方法,这和直接调用run()方法的效果不一样
调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程
6 线程安全是什么
当你的代码中存在多个线程时,运行时 ,每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的
7 Java中静态条件
同一个程序多线程访问同一个资源会,如果对资源的访问顺序敏感,就称存在竞态条件.代码区成为临界区.
最常见的竞态条件为: 先检测后执行
8 notify 和 notifyAll有什么区别
notify 是随机唤醒一个线程, 只有在仅有一个等待线程时, 才会有用
notifyAll是唤醒所有等待的线程
9 为什么wait, notify 和 notifyAll这些方法不在thread类里面
JAVA提供的锁是对象级的而不是线程级的,每个对象都有锁,通过线程获得
如果线程需要等待某些锁那么调用对象中的wait()方法就有意义了。如果wait()方法定义在Thread类中,线程正在等待的是哪个锁就不明显了
10 Java中堆和栈有什么不同
每个线程都有自己的栈内存,用于存储本地变量,方法参数和栈 调用,一个线程中存储的变量对其它线程是不可见的。而堆是所有线程共享的一片公用内存区域。对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己的栈,如果多个线程使用该变量就可能引发问题,这时volatile 变量就可以发挥作用了,它要求线程从主存中读取变量的值
11 线程池是什么? 使用它有什么好处
创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限. 为了避免这些问题,在程序启动的时 候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程
12 怎么检测一个线程是否拥有锁
在java.lang.Thread中有一个方法叫holdsLock(),它返回true如果当且仅当当前线程拥有某个具体对象的锁
13 多线程中的忙循环是什么
忙循环就是程序员用循环让一个线程等待,不像传统方法wait(), sleep() 或 yield() 它们都放弃了CPU控制,而忙循环不会放弃CPU,它就是在运行一个空循环。这么做的目的是为了保留CPU缓存,在多核系统中,一个等待线程醒来的时候可能会在另一个内核运行,这样会重建缓存。为了避免重建缓存和减少等待重建的时间就可以使用它了
14 Java多线程中调用wait() 和 sleep()方法有什么不同
Java程序中wait和sleep都会造成某种形式的暂停,它们可以满足不同的需要,wait()方法用于线程间通信,如果等待条件为真且其它线程被唤醒时它会释放锁,而 sleep()方法仅仅释放CPU资源或者让当前线程停止执行一段时间,但不会释放锁
总结
以上结合网上的资源整理的一些常见的java多线程方面的面试题