0
点赞
收藏
分享

微信扫一扫

【Vue + keep-alive】路由缓存

后来的六六 04-14 11:30 阅读 1

什么是线程和进程?

进程是系统资源调度的基本单位
线程是cpu资源调度分配的最小单位
一个进程有多个线程。

什么是用户线程、内核线程?区别是什么

说说线程的生命周期和状态?

NEW
RUNNABLE
BLOCKED
WAITING
TIME_WAITING
TERMINATED

什么是线程上下文切换?

什么是线程死锁?

循环等待、互斥、不剥夺、请求与保持

sleep() 方法和 wait() 方法对比?

让出资源

主动被动

(重要)可以直接调用 Thread 类的 run 方法吗?Start和run的区别?

同步、异步

JMM(Java 内存模型)详解

什么是JMM?

  • java内存模型
  • 规定了线程和内存之间的关系
  • 约定了一些保证线程安全的规范,比如happen before原则

java线程与主内存的关系

  • 线程内部有共享变量副本
  • 当线程需要通信时,使用共有空间,通过复制的形式共享

什么是指令重排序?特点是什么?

比如一个new运算/

  • 申请内存
  • 初始化值
  • 指向引用对象

只要保证语义一致即可。

happens-before 原则是什么?干嘛用的?

A HB B
就说明语义上A一定发生在B之前。

JMM规定了一些HB规则:
volatile的写 HB 读
解锁 HB 加锁
A HB B HB C – A HB C

并发编程三大特性:(重要)

原子性、可见性、有序性

volatile

两个作用:
保证可见性、保证有序性

可见性,通过提前把内容写入主内存,且要求线程访问时都通过主内存访问,保证了可见性。

有序性,通过内存屏障,把loadload、loadstore等屏障添加在读和写的之前和之后,就可以保证volatile的写一定在读之前,保证了指令重排序

缺点:没有保证原子性

这一点可以用+锁实现

乐观锁和悲观锁

乐观锁:
假想每一次。。。
CAS,重试,不阻塞
缺点,写多时会性能不足

悲观锁:
假想每一次。。。
互斥,阻塞
死锁问题。

乐观锁的实现、问题、如何解决

synchronized

如何使用 synchronized?(重点)

  • 加载实例方法
  • 加载静态方法
  • 加在对象上

构造方法可以用 synchronized 修饰么?

synchronized 底层原理了解吗?

在被锁之前和之后添加monitor enter、exit监视器。

ACC_SYNCHRONIZED

对象的内存布局?

  • 对象头
    • markword
      • lock锁状态
      • biased_lock:偏向锁标志位
      • 轻量级锁标志位,指向线程id
      • 重量级锁标志位,指向monitor的指针
    • 类指针
  • 实例数据
  • 补齐填充

如何查看对象的内存布局及锁状态?

JOL:java object layout

锁优化

1、自旋优化
2、批量重偏向、批量撤销
3、锁粗化

(重点)synchronized 和 volatile 有什么区别?

二者经常一起配合使用,比如单例模式

锁升级

  • 无锁00
  • 偏向锁(mark word对象头中保存线程的id)01
  • 轻量级锁10
  • 重锁11

ReentrantLock是什么?4个特点?

也是一种锁机制,但是比synchronized更灵活。

共同点:

  • 排他锁
  • 可重入锁

不同点:

  • 可充式
  • 非公平和公平
  • 可以指定唤醒
  • 可中断

synchronized+wait+notify
reentrantLock+await+signal(condition)

什么是可重入锁?

比如某一个方法上加了锁,但是这个方法是递归的,那么当同一个线程再次获取同一个对象的时候,可以获取到,就叫做可重入锁。

ReentrantLock加锁的执行流程?

就是AQS的加锁过程

  • state,当前资源是否可用,如果不可用,还要判断当前资源是否为当前线程,如果是则可重入
  • 如果可用,则判断等待队列是否为空,如果为空,则当前线程CAS抢占。否则加入阻塞队列CLH

ReentrantLock释放锁的执行流程

判断占用的是否为当前线程,如果是则state-1
再判断state是否为0.
唤醒等待队列

lock和tryLock的区别?(重要)

lock会阻塞
tryLock不会阻塞,直接返回结果

ReentrantReadWriteLock

前16位是读锁、后16位是写锁
AQS原理。

# 说说CopyOnWriteArrayList

线程安全的List。
原理是:写时复制

缺点:一致性得不到保证

# 说说fail-fast与fail-safe

遍历过程中不可以被修改
遍历过程中可用修改

Automic原子类

基本类型源自类AutomicInteger
数组类型原子类AtomicIntegerArray
引用类型原子类AtomicReference
对象字段更新器AtomicIntegerFieldupdateer

优势

如果不用原子类,计算时需要volatile+锁,保证原子性,但是如果直接使用原子类,就可以更简单的实现原子性。

AQS

介绍AQS?

抽象队列同步器。

有两个重要组成部分:
共享资源状态量state
阻塞队列双向链表CLH

独占锁?

ReentrantLock、ReentrantReadLock

共享资源状态量state为0或1

共享锁?

1、semaphore

  1. 功能:允许一个资源有K个线程同时访问它
  2. 原理:state初始为K,每获取acquire一次-1. 释放release一次+1.当state==0时表示满了,之后的阻塞队列。

2、CountDownLatch

  1. 功能:保证多个线程阻塞到同一个地方,然后一起开始,比如ABCD四个任务同时全部执行完再执行E任务。
  2. 原理:state初始为K,每latch一次-1,主线程await阻塞等待,当state==0时,主线程被唤醒。
  3. 特点:一次性的,用完就没了

如何自己使用AQS

  1. 继承AQS
  2. 重写tryAcquire
    1. CASstate
    2. SetOwnerThread
  3. 重写tryRelease
    1. getState
    2. setState
    3. setOwnerThread

ThreadLocal

作用?

存储结构?

  • ThreadLocalMap:
  • 每个线程都有一个它对应的ThreadLocalMap放在线程本地内存。
  • 每个ThreadLocalMap中的键值对,key表示ThreadLocal、Val表示存入的实际值。

内存泄漏问题?

4种引用类型




虚:用队列接收对象死亡的通知。(实际开发几乎用不到)

Threadlocal的内存泄漏

1、原因

2、为什么不都是弱引用?

3、为什么不都是强引用?

ThreadLocalMap .set/get详解

1、hash算法计算key
2、解决冲突

  1. 如果key为空且val为空,则存入
  2. 如果key不空,则下一个找
  3. 如果key空val不空,则说明此槽位失效,发生探测式清理,然后更新当前槽位

清理分类

探测式清理
启发式清理

扩容机制

  • 如果执行完启发式清理工作后,未清理到任何数据,且当前散列数组中Entry的数量已经达到了列表的扩容阈值(len*2/3),就开始执行rehash()逻辑
  • 先从头到尾清理key=null的槽位(使用expungeStaleEntry的探测式清理方法)、清理完之后再通过判断size >= threshold - threshold / 4 也就是size >= threshold * 3/4 来决定是否扩容。
  • 扩容后的tab的大小为oldLen * 2。遍历老的散列表,重新计算hash位置,然后放到新的tab数组中。

线程池

为什么要用线程池?

  1. 避免线程资源的浪费,线程复用
  2. 减少线程创建过程,加快响应速度
  3. 方便管理

如何创建线程池?

Executor

4种内置线程池
Fixed
Single
Cached(可无限扩容的线程池)
Schedule(定时任务的线程池)

ThreadPoolExecutor

参数:核心线程数、最大线程数、阻塞队列、

饱和处理、KeepAliveTime、UNIT、Factory

执行流程
  1. 先看核心线程满没满,美满就使用核心线程
  2. 再看阻塞队列满没满,没满就加入阻塞队列
  3. 最后看最大线程数满没满,没满就新建不多于最大线程数的一个线程;满了就执行包和策略
饱和策略有哪些?
  1. 默认抛出异常,并抛弃饱和的任务(AbortPolicy)
  2. 直接丢弃饱和任务,什么也不做
  3. 使用主线程执行饱和任务
  4. 用最后一个等待的任务替换饱和任务(CallerRunPolicy)
常用阻塞队列?
  1. LinkedBlockingQueue:Fixed、Single,Cache
  2. ArrayBlockingQueue:不可扩容,不容易OOM,性能较差
  3. DelayedWorkQueue:Schedule
  4. Priority:自定义优先级的线程池

线程数量过大过小都有哪些问题?如何设定线程池的大小?(重要)

线程池数量过大:频繁的上下文切换
过小:CPU资源没有充分利用,且容易导致阻塞队列爆了

N+1:其中1表示防止线程偶发的缺页中断
2 * N或者 N + N * 线程等待时间 / 线程运行时间

线程池的五种状态

RUNNING
SHUTDOWN
STOP
TIDYING
TERMINATED

线程的5种状态

STARTED
RUNNING
WAITING
TIME_WAITING
TERMINATED
BLOCKING

合理关闭线程池?

ShutDown + AwaitTermination

Runnable vs Callable

execute() vs submit()

shutdown()VSshutdownNow()

isShutdown() VS isTerminated()

Future、Callable、FutureTask

Yield、Sleep、Wait、Notify对锁的影响?

# 如何优雅的中断线程

interrupt()
interrupted()
InterruptedExeception

线程的创建有哪几种?

  1. 继承Thread、、、
  2. 实现Callable、、、
  3. 线程池

Run()和Start()/execute()的区别

CPU核心数和线程数的关系

说说进程间的通信

  1. 管道 |
  2. 命名管道 >
  3. 消息队列
  4. 共享内存
  5. socket
举报

相关推荐

0 条评论