多线程基本知识
多线程面试题
线程基本知识
1.进程与线程的区别?
难2出现3
进程是由指令和数据组成,要运行这些指令,数据读写,就要将指令加载到cpu,数据加载到内存。
当一个程序被运行就是开启了一个进程
一个线程就是一个指令流,将指令流一条一条的交给cpu执行,一个进程可以有多个线程
进程和线程区别:
回答
- 进程是正在运行的程序的实例,进程中包含了线程,每个线程执行不同的任务
- 不同的进程之间使用不同的内存空间,当前进程之间可以共享内存空间
- 线程更加轻量级,线程上下文和切换成本比进程小
2.并行和并发有什么区别
难2出现2
单核cpu
1.在单核cpu下实际上还是串行执行的 先去执行线程1再去执行线程2轮着执行
2.操作系统中有一个组件叫做任务调度器的东西,将cpu的时间片分给不同的程序抵用,由于cpu在线程之间切换快说以人感觉就是一起执行的
3.总结为一句话就是微观串行,宏观并行
4.一般将线程轮流使用的做法叫做并发
多核cpu
每个核心都可以调度线程,这个时候线程就是并行
两个cpu可以同时去执行两个线程
区别
- 并发是同一时刻应对多件事情的能力
- 并行是同一时间动手做多件事情的能力
举例子
一个家庭主妇要做饭、打扫、给孩子喂奶、轮流做这事情叫做并发
家庭主妇雇佣了一个保姆,他们一起做这些事情既有并发也有并行
家庭主妇雇佣了三个保姆,一个做饭、一个打扫、一个给孩子喂奶,互不打扰叫做并行
回答
在多核cpu下:
并发是同一时刻应对多件事情的能力,多个线程轮流使用一个或者多个cpu
并行就是同一时间做多件事情的能力,比如4个cpu同时执行4个线程
3.创建线程方式有哪些
难2 出现4
4种创建线程的方式
1.继承Thread类
先继承一个Thread接口 重写方法 然后创建实例对象 调用start方法
2.实现runnable 接口
先实现一个Runnable接口重写run方法 创建对象 调用start方法
3.实现Callable接口
1.继承Callable接口重写call方法可以有泛型 异常 返回值 等等
2.创建接口实例对象
3.创建一个FutureTark
4.然后创建thread对象将futureTark对象赋值给thread对象
5.调用start方法启动线程 用futureTark对象.get可以获得返回值
4.线程池创建线程
继承thread或者实现runnable创建任务 然后创建线程池对象实例 用线程池对象实例去调用submit方法 将刚刚创建的任务提交 最后关闭线程池
回答
继承Thread类
实现runnable 接口
实现Callable接口
线程池创建线程 回答追问在说区别
runnable和callable有什么区别
回答
- Runnable接口run方法没有返回值 run的异常只能在内部消化不能继续向上抛出
- Callable接口有返回值和FutureTack配合get方法获取线程的执行结果,有泛型,可以抛出异常
启动线程可以使用run方法吗 用run和start有什么区别
回答
可以使用但是run方法使用是在主线程去运行相当于去调用一个普通方法 而start方法是开启一个线程去异步的运行,不可以开启多次开启线程,只能被调用一次
4.线程包含哪些状态
难3出现4
参考Thread类中的枚举方法
6种
NEW,RUNNABLE,BLOCKED,WATING,TIMED_WAITNG,TERMINATED
public enum State {
/**
* 尚未启动的线程的线程状态。.
*/
NEW,
/**
* 可运行线程的线程状态。可运行线程中的一个线程
* 状态在Java虚拟机中执行,但它可能等待来自操作系统的其他资源
*如处理机.
*/
RUNNABLE,
/**
* 等待监视器锁的线程的线程状态。
* 处于阻塞状态的线程正在等待监视器锁
* 进入同步块/方法或
* 调用后重新进入同步块/方法
* {@link Object#wait() Object.wait}。
*/
BLOCKED,
/**
等待线程的线程状态。 线程处于等待状态
*/
WAITING,
/**
*指定等待时间的等待线程状态。线程由于调用其中一个而处于定时等待状态
*/
TIMED_WAITING,
/**
*终止线程的线程状态。
*线程已经完成执行。
*/
TERMINATED;
}
当一个线程新建出来就是新建状态,调用了start()方法之后就变成了可运行状态,可运行状态分成了就绪(抢到cpu执行权利之后变成运行)和运行状态,执行完之后变成死亡状态,之间有可能加锁就是没有执行的权利就进入阻塞状态,还有可能是调用了wait()方法就变成了等待状态等待别人调用notify()方法,还有就是调用了sleep(时间)方法就是变成了即使等待状态,等待时间到
5.新建三个线程怎么保证他们的循序执行
难2出现3
使用线程中的join方法
join()等待线程运行结束 加入冒一个线程 等待那个线程完了之后在调用这个线程
阻塞调用此方法的线程进入即时等待状态

6.notify()和notiftyAll()有什么区别
难2出现3
- notiftyAll()所有wait()的线程
- noti唤醒一个调用了wait方法的线程
7.java中的wait()和sleep()有什么不同
难3出现3
wait() wait(时间) 到时间之后可以自动唤醒
共同点:都能让当前线程暂时放弃cpu的使用权,进入阻塞状态
不同点:
1.方法的归属不同
-
sleep属于Thread的静态方法
-
wait(),wait(long)属于object的方法每个对象都默认有
2.醒来的时机不一样
-
带参数的到时间之后都可以被自动的唤醒
-
wait(),wait(long)还可以被notify唤醒,wait()如果不唤醒就会一直等下去
-
他们都可被打断唤醒
3.锁特性不同
-
wait()必须配合锁对象使用 先获取锁对象,而sleep不用
-
wait执行完后之后会释放锁对象,其他线程可以调用。sleep方法在锁中执行不会释放对象 一个是放弃cpu使用权其他人可以用一个是啊放弃之后你们也不能用

8.怎么停止一个正在运行的线程
难2出现3
3种方式退出线程
1.新建一个退出标记 正常的退出线程


2.使用stop方法强制终止,已经作废(不推荐使用)
3.使用interrupt方法中断线程,
- 打断阻塞的线程的线程会抛出打断异常
- 打断正常的线程,可以更具打断状态来标记是否退出线程和第一种差不多
本文基于黑马程序员的面试篇b站

浙公网安备 33010602011771号