自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(129)
  • 收藏
  • 关注

原创 spring security部分源码分析 鉴权流程

鉴权的流程在FilterSecurityInterceptor中我们需要先执行登陆的操作,然后访问一个需要有权限鉴定的接口,进入org.springframework.security.web.access.intercept.FilterSecurityInterceptor#doFilter方法进入org.springframework.security.access.intercept.AbstractSecurityInterceptor#beforeInvocationorg.spring

2022-07-06 22:41:43 292 1

原创 spring security部分源码分析 记住我的功能

在security 的UsernamePasswordAuthenticationFilter 登陆成功时会进入rememberMeServices.loginSuccess的逻辑进入org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl#createNewToken之后如果再进行登陆,那么就会在RememberMeAuthenticationFilter过滤器执行记住我的逻辑...

2022-07-01 00:01:59 228

原创 spring security部分源码分析 认证流程

spring security 认证流程部分源码

2022-06-15 22:42:41 166

原创 spring security部分源码分析 过滤器加载流程

在引入的springframework.boot.autoconfigure的包中的spring.factories中注入了//过滤器自动配置org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration

2022-06-08 22:06:18 199

原创 OAuth2的简单使用

OAuth2 协议:认证服务器允许⽤户授权第三⽅应⽤访问他们存储在另外的服务提供者(用户服务)上的信息,⽽不需要将⽤户名和密码提供给第三⽅应⽤或分享他们数据的所有内容Spring Cloud OAuth2 是 Spring Cloud 体系对OAuth2协议的实现,可以⽤来做多个微服务的统⼀认证(验证身份合法性)授权(验证权限)。通过向OAuth2服务(统⼀认证授权服务)发送某个类型的grant_type进⾏集中认证和授权,从⽽获得access_token(访问令牌),⽽这个token是受其他微服务信任

2022-02-15 16:46:21 1288

原创 java常用指令

jpsjps用来查看java进程及其相关的信息jps [options] [hostid]options:-l : 显示进程id,显示主类全名或jar路径-q : 显示进程id-m : 显示进程id, 显示JVM启动时传递给main()的参数-v : 显示进程id,显示JVM启动时显示指定的JVM参数jinfojinfo是用来查看JVM参数和动态修改部分JVM参数的命令jinfo [option] <pid>options:不加[option] 输出所有的系统属性和

2021-12-24 18:28:25 1162

原创 垃圾收集器

垃圾收集器可以分为串行收集器(新生代串行收集器Serial,老年代串行收集器 Serial Old),并行收集器(新生代ParNew收集器,新生代ParallelGC收集器,老年代ParallelGC收集器),CMS收集器,G1收集器串行收集器(Serial):串行垃圾回收是为单线程环境设计且只使用一个线程进行垃圾回收,会暂停所有的用户线程。并行收集器:多个垃圾收集器线程并行工作,同样会暂停用户线程。CMS收集器:用户线程和垃圾回收线程同时执行,不一定是并行的,可能是交替执行,可能一边垃圾回收,一边运

2021-12-14 16:20:12 482

原创 垃圾收集算法

垃圾收集可以分为部分收集和整堆收集部分收集包括新生代收集(Minor GC/Young GC),老年代收集(Major GC/Old GC)如CMS收集器,混合收集(Mixed GC)如有G1收集器整堆收集(Full GC)即 收集整个Java堆和方法区的垃圾收集标记-清除算法标记-清除算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以反过来,标记存活的对象,统一回收所有未被标记的对象。标记-清除算法有两个不足之处:第一个是执行

2021-11-30 20:42:10 81

原创 引用计数法和可达性分析算法

垃圾回收的区域:方法区,堆引用计数法栈中有对堆中的对象有引用,如果失去了这个引用关系,那么这个对象就需要被回收在引用计数法中当一个对象被引用时,这个对象的的计数值+1,失去引用时,计数值-1,当计数值为0时表示对象需要被回收,但是引用计数法无法检测循环引用。循环引用:有AB对象,这两个对象互相引用,除了这个互相引用没有地方在使用这两个对象,所以这两个对象时应该是要被回收,但是因为它们的引用计数都是1,无法被回收可达性分析算法可达性分析算法:从GC root 出发,向下开始搜索引用的对象,搜索经

2021-11-29 16:00:28 317

原创 类加载器的类型

类的加载阶段将类的.class文件中的二进制数据读入到内存中,将其常量池、属性表、方法表、异常表放在运行时数据区的方法区内,然后在创建一个对应的java.lang.Class对象,用来封装类在方法区内的数据结构JVM主要在程序第一次主动使用类的时候,才会去加载该类,而且只加载一次jvm支持两种类型的加载器,分别是引导类加载器()和自定义加载器,引导类加载器是由c/c++实现的,自定义加载器是由java实现的。自定义加载器相当于ClassLoader的子类,它包括扩展类加载器(Extension Clas

2021-11-22 20:20:45 531

原创 类加载的执行过程

代码经过编译后成为了.class文件,类加载子系统负责从文件系统中或是网络中加载.class文件,加载后的class类信息放在方法区,类加载器只负责加载,是否运行由执行引擎决定加载预加载虚拟机启动的时候会加载JAVA_HOME/lib/rt.jar中的.class文件例如java.lang.*,java.util*,java.io.*等...

2021-11-10 22:10:06 2110

原创 栈溢出的原因

栈的大小用-Xss来设置当线程请求的栈深度大于虚拟机所允许的最大深度, 将抛出StackOverflowError异常public class StackOverflowErrorTest { static int times = 1; public static void main(String[] args) { try { self(); //捕获error而非Exception } catch (

2021-11-04 22:15:59 299

原创 jvm堆溢出

不停的创建对象,并且这些对象不会被垃圾回收的话,当对象所占空间超过了堆的最大空间的话会抛出OutOfMemoryError异常public class HeapOOMTest { public static void main(String[] args) { List<Object> oomObjectList = new ArrayList<>(); while (true) { oomObjectList.add

2021-11-02 17:46:22 147

原创 jvm运行时内存

jdk7中的内存结构jdk8中的内存结构线程私有的:程序计数器,虚拟机栈,本地方法栈线程共享的:堆,方法区,元空间,直接内存java8之后方法区的变化:元空间替换永久代,永久代中的类原信息转移到了本地内存,字符串常量池和静态变量转移到了堆程序计数器程序计数器是当前线程字节码的行号提示器,在字节码解释器工作的时候改变程序计数器的值来选取下一条将要执行的字节码指令。分支、循环、跳转、异常、线程恢复等都靠这个程序计数器完成。一个cpu同一时间只能执行一个cpu中的命令,线程未执行完的命令,会保

2021-10-29 22:37:44 519 5

原创 CompletableFuture的使用和部分原理

CompletableFuture是一个异步编程工具类简单使用 CompletableFuture<String> completableFuture = new CompletableFuture<>(); new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) {

2021-10-19 22:36:55 405

原创 ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor可以按时间来执行任务,它继承了ThreadPoolExecutor构造方法 public ScheduledThreadPoolExecutor(int corePoolSize) { //使用ThreadPoolExecutor的构造方法 //DelayedWorkQueue是ScheduledThreadPoolExecutor内部自己实现的阻塞队列 super(corePoolSize, Integer

2021-10-10 18:58:48 103

原创 ThreadPoolExecutor

ThreadPoolExecutor的核心数据结构public class ThreadPoolExecutor extends AbstractExecutorService { //记录线程池的状态和线程的个数 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); //存放待执行的任务的阻塞队列 private final BlockingQueue<Runnable> workQueue;

2021-09-22 22:04:51 71

原创 读写锁ReentrantReadWriteLock

读线程与读线程之间不互斥public interface ReadWriteLock { Lock readLock(); Lock writeLock();}ReentrantReadWriteLock实现了这个接口ReentrantReadWriteLock的使用方法ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); Lock readLock = readWriteLock.readLock(); r

2021-09-15 23:22:34 95

原创 AtomicIntegerFieldUpdater

如果一个类是自己编写的,则可以在编写的时候把成员变量定义为Atomic类型。但如果是一个已经有的类,在不能更改其源代码的情况下,要想实现对其成员变量的原子操作,就需要AtomicIntegerFieldUpdater、AtomicLongFieldUpdater 和 AtomicReferenceFieldUpdater。AtomicIntegerFieldUpdater的使用 public static void main(String[] args) { Student stu

2021-09-13 18:29:54 1198

原创 AtomicStampedReference

AtomicInteger,AtomicBoolean,AtomicReference都是根据value的是否变化来做cas修改的,但是这样无法解决ABA的问题AtomicStampedReference类不仅比较了对象还比较了版本号AtomicStampedReference的使用 Object obj = new Object(); int initialStamp = 0; AtomicStampedReference atomicStampedRe

2021-09-10 14:55:58 299

原创 AtomicInteger,AtomicBoolean,AtomicReference

AtomicInteger的使用public static void main(String[] args) { AtomicInteger atomicInteger = new AtomicInteger(); atomicInteger.getAndIncrement(); atomicInteger.getAndDecrement();}AtomicInteger的属性private static final Unsafe unsafe = Unsafe.getUn

2021-09-09 18:21:10 90

原创 同步工具类 Phaser

Phaser是CyclicBarrier和CountDownLatch的加强版,jdk1.7增加的一个类Phaser代替CountDownLatch:主线程等待5个worker线程运行结束 Phaser phaser = new Phaser(5); System.out.println("线程启动"); Random random = new Random(); for (int i = 0; i < 5; i++) {

2021-09-08 14:36:32 79

原创 同步工具类CyclicBarrier

使用场景:多个线程都到达某个状态后,一起进入下个阶段使用方法:CyclicBarrier barrier = new CyclicBarrier(5); barrier.await();举例public class CyclicBarrierTest { public static void main(String[] args) { CyclicBarrier barrier = new CyclicBarrier(5,()-> System.out.printl

2021-09-06 16:02:27 66

原创 同步工具类CountDownLatch

一个线程要等待5个worker线程执行完才退出可以用CountDownLatchCountDownLatch latch = new CountDownLatch(5); Random random = new Random(); for (int i = 0; i <5 ; i++) { new Thread(()->{ try { Thread.sleep(ran

2021-09-03 18:20:31 42

原创 同步工具类Semaphore

Semaphore提供了资源数量的并发访问控制,也就是线程的并发量代码使用//一开始有5份共享资源,即5个线程并发量。第二个参数表示是否是公平Semaphore semaphore = new Semaphore(5,true);// 工作线程每获取一份资源,就在该对象上记下来// 在获取的时候是按照公平的方式还是非公平的方式,要看上面代码的第二个参数是否公平。 // 一般非公平抢占效率较高。semaphore.acquire();// 工作线程每归还一份资源,就在该对象上记下来 //

2021-09-02 18:09:47 55

原创 ConcurrentHashMap

ConcurrentHashMap由数组+链表+红黑树组成数组中存放的是链表的头结点,或者红黑树的根节点如果头节点是Node类型,它后面的的就是一个普通的链表;如果头节点是TreeNode类型,它的后面就是一颗红黑树,TreeNode是Node的子类链表和红黑树之间可以相互转换:初始的时候是链表,当链表中的元素超过某个阈值时,把链表转换成红黑树;当红黑树中的元素个数小于某个阈值时,再转换为链表。构造方法 public ConcurrentHashMap(int initialCapacit

2021-08-31 22:30:33 57

原创 ConcurrentLinkedQueue

ConcurrentLinkedQueueConcurrentLinkedQueue 的实现原理和AQS内部的阻塞队列类似,AQS是基于双向链表,通过对head/tail进行CAS操作,实现入队和出队,队列里面放的是线程,而ConcurrentLinkedQueue是一个单向链表,里面放的是实际的元素public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> implementsQueue<E>, j

2021-08-24 23:33:39 118

原创 CopyOnWriteArrayList

CopyOnWrite指在“写”的时候,不是直接“写”源数据,而是把数据拷贝一份进行修改,再通过悲观 锁或者乐观锁的方式写回。拷贝一份修改是为了在“读”的时候不加锁CopyOnWriteArrayListCopyOnWriteArrayList的核心数据结构是一个数组 arraypublic class CopyOnWriteArrayList<E> implements List<E>, RandomAccess,Cloneable, java.io.Serializab

2021-08-23 22:31:55 80

原创 LinkedBlockingDeque

BlockingDequeBlockingDeque定义了一个双端队列public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> { void putFirst(E e) throws InterruptedException; void putLast(E e) throws InterruptedException; E takeFirst() throws In

2021-08-18 23:25:04 58

原创 SynchronousQueue

SynchronousQueueSynchronousQueue是一种特殊的BlockingQueue,它本身没有容量。先调put(e),线程会阻塞;直到另外一个线程调用了take(),两个线程才同时解锁,反之亦然。对于多个线程而言,例如3个线程,调用3次put(e),3个线程都会阻塞;直到另外的线程调用3次take()。public SynchronousQueue(boolean fair) { //fair是否是公平的,公平先进先出(队列),不公平先进后出(栈) transferer

2021-08-18 00:21:53 117

原创 condition的await是否会释放线程占有的reentrantLock

public class ThreadTest { public static void main(String[] args) throws InterruptedException { ReentrantLock reentrantLock = new ReentrantLock(); Condition condition = reentrantLock.newCondition(); new Thread(() -> {

2021-08-12 00:34:40 3686

原创 PriorityBlockingQueue和DelayQueue

PriorityBlockingQueuePriorityQueue(优先级阻塞队列)是按照元素的优先级从小到大出队列的。正因为如此, PriorityQueue元素之间需要可以比较大小(使用PriorityBlockingQueue的Comparator,或者元素实现Comparable)。public class PriorityBlockingQueue<E> extends AbstractQueue<E> implementsBlockingQueue<E&gt

2021-08-05 23:40:05 135

原创 LinkedBlockingQueue和ArrayBlockingQueue

BlockingQueue接口BlockingQueue是一个先进先出带阻塞功能的队列,当入队列时,若队列已满,则阻塞调用者;当出队列时,若队列为空,则阻塞调用者。public interface BlockingQueue<E> extends Queue<E> { //... boolean add(E e); boolean offer(E e); void put(E e) throws InterruptedException;

2021-08-05 00:20:19 253

原创 jmm内存模型

一个cpu下有多个核心,每个核心有自己的L1,L2级缓存,所有核公用一个L3级缓存因为存在CPU缓存一致性协议(例如MESI),多个CPU核心之间缓存不会出现不同步的问题(L1L2L3是同步的),即不存在内存可见性问题。缓存一致性协议对性能有很大损耗,为了解决这个问题,又进行了各种优化。例如,在计算单元和L1之间加了Store Buffer、Load Buffer(还有其他各种Buffer)L1、L2、L3和主内存之间是同步的,有缓存一致性协议的保证,但是Store Buffer、Load Bu

2021-08-03 22:38:20 175

原创 优雅的关闭线程

在Java中,有stop()、destory()等方法,但这些方法官方明确不建议使用。原因很简单,如果强制杀死线程,则线程中所使用的资源,例如文件描述符、网络连接等无法正常关闭。可以使用标志位关闭循环线程代码实现public class MyThread extends Thread { //声明一个停止标志位 private boolean running = true; @Override public void run() { while (ru

2021-08-01 23:55:27 92

原创 线程的interrupt

InterruptedException异常:声明了抛出InterruptedException异常的方法(轻量级阻塞的方法),线程在阻塞时,其他线程(比如主线程)调用这个线程的interrupt()方法,阻塞线程会抛出InterruptedException异常并从阻塞状态中跳出。声明了InterruptedException的方法有public static native void sleep(long millis) throws InterruptedException{//...}publ

2021-07-31 00:51:02 133

原创 使用wait notify实现生产者消费者模型

一个内存队列,多个生产者线程往内存队列中放数据;多个消费者线程从内存队列中取数据使用wait()与notify()机制队列的实现public class MyQueue { /** * 数组队列(总长度为10) */ private String[] data = new String[10]; /** * 出队列的下标 */ private int getIndex = 0; /** * 入队列的下标

2021-07-28 00:37:38 170

原创 synchronized关键字

public Class MyClass { //实例方法 public synchronized void method1() { // ... } //静态方法 public synchronized static void method2() { // ... }}如果此时有一个对象MyClass myClass = new MyClass(),那么调用实例方法myClass.method1()的锁是加在myCla

2021-07-25 00:38:12 47 1

原创 Thread基础

java中创建执行线程的两种方法继承Thread类。public class MyThread extends Thread { @Override public void run() { while (true) { System.out.println(Thread.currentThread().getName() + " 运行了"); try { Thread.sleep(2000)

2021-07-23 23:42:06 101 1

原创 并发编程基础

并发编程三要素原子性:即一个不可再被分割的颗粒。在Java中原子性指的是一个或多个操作要么全部执行成功要么全部执行失败。有序性:程序执行的顺序按照代码的先后顺序执行。(处理器可能会对指令进行重排序)可见性:当多个线程访问同一个变量时,如果其中一个线程对其作了修改,其他线程能立即获取到最新的值(处理本地缓存)。线程的五大状态创建状态:当用new操作符创建一个线程的时候就绪状态:调用start方法,处于就绪状态的线程并不一定马上就会执行run方法,还需要等待CPU的调度运行状态:CPU开始调度线程

2021-07-19 00:10:33 106

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除