多线程面试题

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

三种。

继承Thread类

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

线程与进程的区别???

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

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

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

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

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

两种。

同步代码块

多线程面试题_第1张图片

同步代码块

同步方法:

多线程面试题_第2张图片

同步方法

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

启动线程用 start();

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

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

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

sleep()和wait()方法的区别???

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

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

多线程面试题_第3张图片

区别比较

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

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

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

线程的生命周期???

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

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

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

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

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

1.sleep

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

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

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

多线程面试题_第4张图片

线程生命周期图解

如何避免死锁???

Java多线程中的死锁

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

多线程面试题_第5张图片

死锁发生的四个条件

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

                

你可能感兴趣的:(Java面试)