多线程基本知识
多线程面试题
线程基本知识
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类

2.实现runnable 接口

先实现一个Runnable接口重写run方法 创建对象 调用start方法
3.实现Callable接口

1.继承Callable接口重写call方法可以有泛型 异常 返回值 等等
2.创建接口实例对象
3.创建一个FutureTark<string>对象将接口实例对象复制给他
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站