文章目录
- 聊聊进程与线程
进程是指内存中运行的应用程序,每个进程独享一块内存空间;
而一个进程可以拥有多个线程,同一个进程内的各个线程共享一块内存空间,因此切换进程比切换线程开销大,
线程更加轻量级。
- 线程的方法有哪些?
start():启动线程,从而调用run()方法;
run():启动这个线程真正要实现的逻辑,创建线程时要对这个方法进行覆写,提供你希望这个线程要执行的任务指令
sleep():让线程休眠,但不会释放锁资源;
yield():让一个正在执行的线程交出运行权;
join():等待指定线程运行结束后再运行;
stop()、suspend():已被弃用,会造成线程不安全或者死锁
- 聊聊线程同步
线程同步是指线程之间按照某种机制协调先后次序执行,对一块内存进行操作;
如何实现线程同步:
1.使用volatile关键字修饰变量:适用于一写多读的并发场景,因为volatile关键字并不保证原子性,但是可以保证被修饰的变量一经修改就写到主存当中,来实现线程间的可见性
2.JUC包下线程通信工具如Semaphore ,、CountDownLatch
3.JUC包下的原子包装类;
4.线程池(下面讲)
- 线程池知道吗
- 线程池是什么?
是一种利用池化思想避免频繁地创建与销毁线程造成系统资源的浪费; - 创建线程池时的核心参数?
corePoolSize:核心线程数
maximumPoolSize:线程池可容纳的最大线程数
allowCoreThreadTimeOut:核心线程超时是否销毁的标志位
keepAliveTime:最大空闲时间,当一个非核心线程空闲超过这个时间,就会被销毁,如果设置allowCoreThread1TImeOut为true,核心线程也这样;
unit:keepAliveTime的单位
workQueue:任务队列
threadFactory:线程工厂
handler:拒绝策略 - 线程池的工作流程(讲故事来回答)
假设一个线程池核心线程数为5,最大线程数为10,任务队列长度是10:
(1)新任务来,优先用核心线程来执行;
(2)核心线程都用完了,新任务来去任务队列排队;
(3)任务队列排满10位,再来一个新任务,开辟一个新线程来执行;
(4)当工作线程达到最大线程数,任务队列也排完执行拒绝策略; - 线程的拒绝策略有哪些?
1.异常策略:抛异常,默认策略;
2.丢弃策略:丢掉想挤进来来的任务;
3.牺牲策略:牺牲掉在排队中最早进来但没被处理的任务;
4.执行策略:阻塞一段时间等待线程空闲然后执行它,相当于插队;
- 什么是死锁,死锁产生的必要性,如何避免死锁?
- 讲故事回答:
线程A持有锁资源1,并请求锁资源2,而线程B持有锁资源2,在请求锁资源1,两个线程都不肯放弃持有资源,一直等待阻塞的现象; - 死锁产生的四个必要条件:
1.互斥:一个锁资源同一时间只能被一个线程所持有
2.持有并等待:一个线程持有一个资源,再去请求另一个资源,
并对自己持有的资源不放;
3.不剥夺:线程已持有的资源,另外一个线程不能对他进行剥夺;
4.环路等待:产生死锁的线程间形成一套循环链 - 如何避免死锁?
1.在一个线程内一次性把所有要用的资源的申请了;
2.当一个线程申请不到资源时,主动放弃自己持有的资源;
3.设置资源申请的前置条件,就像要申请资源2必须要拥有资源1;
- 线程安全的集合了解多少?
- CopyOnWriteArrayList
(待补充) - ConcurrentHashMap
(待补充)
- Socket是什么?
Socket是应用层与传输层中间的一层软件抽象层,是一组对TCP/IP协议或者UDP的API,在Java环境下,一般指基于TCP/IP协议的网络编程;
Socket通信的过程?
基于TCP:服务器端初始化Socket,然后绑定端口,对该端口进行监听(listen),调用accept方法,等待客户端连接;
客户端则初始化一个Socket,调用connect方法,连接服务器的Socket,连接成功,则开始请求数据,完成后就关闭连接;
即:1.服务器监听;2.客户端请求;3.连接确认
- TCP与UDP
TCP面向连接的,发送数据前先建立连接,是可靠的服务,传输的数据不会丢失,不会重复,且按顺序到达;
UDP是无连接的,不具备可靠性
2.
TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多;
3.
TCP是面向字节流的,UDP是面向报文的;
4.
对实时性要求高的场景使用UDP,如:媒体通信,直播;
要求传输内容可靠,出现丢失就用TCP
- TCP的三次握手
- 客户端想服务端发送SYN;
- 服务端返回SYN,ACK
- 客户端发送ACK
第一次握手,客服端什么都无法确认;服务端确认的对方发送正常,自己接收正常
第二次握手,客户端确认自己发送正常,自己接收正常;服务端确认对方发送正常,自己接收正常;
第三次握手,双方都确认自己和对方收发正常;
三次握手的原因:
1.防止历史连接;
2.同步双方的初始序列号;
3.避免资源浪费