JAVA基础
2021-02-24 16:27:07 15 举报
AI智能生成
个人Java基础总结,有不对的地方欢迎斧正
作者其他创作
大纲/内容
JAVA基础
消息队列
RabbitMq
Kafka
RacketMq
Spring
DI 注入
依赖注入时IOC控制反转的另外一个角度的描述,在使用某个类时,只需要告诉容器就能获取到该类的对象。这就是依赖注入
IOC 控制反转
控制:控制了对象的创建
反转:反转了对象的注入方式
实现方式:在程序启动时,通过解析XML来创建对象并放入容器当中,该部分主要涉及的类为:ApplicationContext
AOP 切面
简介:Aop时Oop的延续,面向对象中关注更多的时对象。而在Aop中关注更多的时切面
实现方式:AspectJ、SpringAop、JBossAop
通知类型
After Advice(后置通知)
Before Advice(前置通知)
After Returning Advice(返回之后通知)
After Throwing Advice(抛出异常后通知)
Around Advice(环绕通知)
JDK代理
如果被代理的类实现了相关接口,那么Spring会默认使用JDK代理
CgLib代理
如果被代理的类没有实现接口,那么Spring会使用CgLib代理
SpringMVC
执行过程
1. 用户请求->前端控制器
2. 前端控制器->根据URL来获取到对应的控制器
3. 对应请求的控制器->执行相关代码逻辑
4. 执行成功后返回ModelAndView
5. 进行视图解析
6. 进行页面渲染
7. 前端控制器将ModelAndView或View返回给用户
分布式
分布式锁
实现方式:Redis、Memcached
该两种实现方式都是利用了相关缓存的原子性
雪崩
缓存穿透
集合
Map
HashMap
线程不安全
数组+列表来实现
查询速度快O(logn)
Key可以为null,但是只能存在1条为null的数据,Value可以多条数据为null
默认大小为16,加载因子为0.75f
继承AbstractMap,实现了Serializeable、Cloneable、Map接口
Jdk8中,当Key的长度大于8之后将不再是链表形式存储,而是通过treeifyBin()方法将连边转换为红黑树来存储
LinkedHashMap
实现是可以理解成HashMap+LinkList实现的,通过HashMap的数据结构保证查询速度,通过LinkList来保存插入顺序
Key和Value都可以为null,Key只能由一条为null的记录,Value可以存在多条记录为null
TreeMap
Key可以为null,但是只能存在1条为null的数据。Value可以多条数据为null
继承Dictionary,实现了Serializable、Cloneable、Map接口
HashTable
线程安全,底层方法使用了synchronize关键字来保证线程安全
查询速度由于要保证线程安全,所以查询效率不如HashMap
Key和Value都不可以为null
ConcurrentHashMap
线程安全,实现线程安全是由分段式锁来实现的
由于使用分段式锁来实现的,所以查询速度相对HashTable来说,要高一些
Key和Value都不能为null
Set
HashSet
利用了HashMap的Key来实现的,线程不安全
TreeSet
利用了TreeMap的Key来实现的,线程不安全
LinkedHashSet
利用了LinkedHashMap的key来实现,线程不安全
List
ArrayList
实现原理为可变数组
初始容量为10,每次扩充为当前容量的一半+1
查询速度为O(n)
LinkList
实现原理为双向链表
Vector
线程安全,相关操作方法使用了synchronize关键字修饰来保证线程安全
初始容量为10,每次扩充为当前容量的一半
多线程
什么是线程?
线程是计算机Cpu的最小执行单元。同时也是Cpu实际执行单位
线程的状态
New(初始化状态)
Runnable(可执行状态)通过start()方法来将线程推进到该状态
Running(执行状态)待Runnable状态的线程抢占到CPU后线程会进入到该状态
Dead(执行结束)线程的Run()方法执行完毕后进入到该状态
Blocked(阻塞状态)
由wait()造成的阻塞
由sleep()或者join()造成的阻塞
由于锁(synchronize)被抢占造成的阻塞
暂停线程的api
sleep()
该方法会释放CPU使用权,但是不会释放锁。等待时间结束后,线程会进入Runnable状态。所以实际休眠的时间可能会大于设定时间
该方法存在于Thread中,可以在任何地方调用。而且需要捕获异常
wait()
该方法会释放CPU使用权,同时也会释放锁。通过notify()或者notifyAll()来唤醒线程,如果该线程可以获得锁,则进入Runnable状态,否则该线程还会处于阻塞状态
该方法只能在线程run()代码块中使用
yield()
该方法会让线程放弃当前的CPU资源,将资源让给其他同等优先级的线程。但是该方法不一定生效,因为线程再放弃CPU资源时,很可能又被CPU时间片选中。所以该方法可能不会生效
唤醒线程的api
前情提要:线程中会有等待池和锁池
锁池
线程在取得锁之后,另外的线程再来获取该锁时会进入锁池当中
等待池
线程运行中,如若调用了wait()方法,那么该线程会进入到等待池中
notify()
唤醒等待池中随机的一个线程
notifyAll()
唤醒等待池中的所有线程
特殊api
join()
该方法可以等待某个线程执行结束后再执行另外的线程,如T1,T2两个线程,T1.start()之后T1.join()之后T2.start()这样T2线程会在T1线程执行完毕后再执行
锁
synchronize
这种同步机制是jvm层级的,同时也会自己释放锁资源。实现的是悲观锁,是由线程独占的
又java原生提供的同步关键字,在需要同步的地方使用该关键字。该关键字可以加在方法、或者特定的代码块上,括号中为该同步的锁对象
Lock
Lock是代码层级实现的锁机制。由于Lock是接口,所以常用的锁是他的实现类:ReentrantLock
ReentrantLock
使用需要手动指定锁开始的地方,同时必须手动指定锁结束的地方
ReentrantLock是可重入锁,也就是说可以在代码中重复调用lock,但是在归还锁时也需要调用同样次数的unlock方法
公平锁
公平锁是指按找获取锁的顺序来获取锁,这种方式对吞吐量有影响。如果排在前面的线程执行过慢,则会长时间占有锁。导致其他线程长时间阻塞
非公平锁
非公平锁表示让要获取该锁的线程都尝试获取该锁,如果能获取到则直接获取锁,其他线程进入阻塞状态
创建线程的方法
继承Thread类,重写Run方法
特点:由于需要继承Tread类,所以该方法灵活性较低
实现Runnable接口,实现Run方法
特点:灵活性高,因为java是单继承,多实现的
实现Callable接口,实现Call方法
特点:该种方式有返回值。可以获取线程最终的执行结果
线程池
线程池的相关参数
corePoolSize(核心线程数):线程池中常驻常驻的线程数
线程池在初始化时时没有线程的,只有在任务提交时才会区创建线程
maximumPoolSize(最大线程数):在核心线程数的基础上会增加一些非核心线程
只有当workQueue任务队列满了之后才会创建多余核心线程数的非核心线程,最大为该值
keepAliveTime(最大生存时长):非核心线程的最大生存时长
unit(最大生存时长的单位):对应的时TimeUnit类
workQueue(任务队列):当提交的任务数量大于核心线程数时,则会将任务存储在该队列中
无界任务队列(LinkedBlockingQueue):队列长度无限,多余的任务会放入该队列,但是任务较多时,程序会发生OOM异常
有界任务队列(ArrayBlockingQueue):队列长度有限,多余的任务会存入该队列,超过该队列后会创建由非核心线程去执行,如果非核心线程也达到上限,则会进入到线程池拒绝策略流程当中
同步移交队列(SynchronizeQueue):该项代表队列不作为缓冲区,可以理解为队列容量为0
threadFactory(创建线程的工厂)
默认使用Executors.defaultThreadFactory(),可以指定使用guava库的ThreadFactoryBuilder
handler(线程池饱和策略)
AbortPolicy
饱和拒绝策略:当任务队列和非核心线程数都达到上限时,抛出该RejectedExcutionedException
CallerRunsPolicy
自己执行策略:当任务队列和非核心线程数都达到上限时,会调用线程自己的excute或者run方法,而不是再交给线程池去执行
DiscardOldestPolicy
丢弃队列中等待时间最久的策略,当任务队列和非核心线程数都达到上线时,会将等待时间最久的任务放弃掉,将该任务加入到队列当中
DiscardPolicy
丢弃策略:丢弃当前新增的任务,不做任何处理
FixThreadPool(int size)
固定线程池,线程数量为方法参数的size,超过线程数量时,会将超过的任务放入到任务队列当中
SingleThreadPoolExecutor()
单线程线程池,只提供一个线程的线程池,可指定线程执行顺序。如FIFO
CashedThreadPool()
可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
ScheduledThreadPool()
可定期或者延时执行任务的定长线程池,支持定时及周期性任务执行。
JVM
ClassLoader
双亲委派机制
运行时数据区
JVM内存模型
堆
线程共享区域
存储对象
Java栈
每个线程私有
存储基本数据类型,和对象的地址
本地方法栈
线程私有
负责调用操作系统的相关方法
方法区
线程共享
存储常量、静态类和类的相关信息
程序计数器
volatile
可见性
用该关键字修饰的变量在cpu执行后会马上将该操作从Cpu的高速缓存中同步到内存当中
无法保证原子性
volatile无法保证原子性,虽然voliate保证了变量的可见性,但是会出现覆盖告诉缓存的情况。所以volatile无法保证原子性
上述情况为:当某个线程读取到变量时此时变量值为10,执行+1操作时没有抢占到CPU。此时线程被阻塞。
有序性
使用volatile关键字可以保证指令集执行的有序性,而不让JVM进行指令重排
0 条评论
下一页