- 博客(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 348 1
原创 spring security部分源码分析 记住我的功能
在security 的UsernamePasswordAuthenticationFilter 登陆成功时会进入rememberMeServices.loginSuccess的逻辑进入org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl#createNewToken之后如果再进行登陆,那么就会在RememberMeAuthenticationFilter过滤器执行记住我的逻辑...
2022-07-01 00:01:59 291
原创 spring security部分源码分析 过滤器加载流程
在引入的springframework.boot.autoconfigure的包中的spring.factories中注入了//过滤器自动配置org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
2022-06-08 22:06:18 238
原创 OAuth2的简单使用
OAuth2 协议:认证服务器允许⽤户授权第三⽅应⽤访问他们存储在另外的服务提供者(用户服务)上的信息,⽽不需要将⽤户名和密码提供给第三⽅应⽤或分享他们数据的所有内容Spring Cloud OAuth2 是 Spring Cloud 体系对OAuth2协议的实现,可以⽤来做多个微服务的统⼀认证(验证身份合法性)授权(验证权限)。通过向OAuth2服务(统⼀认证授权服务)发送某个类型的grant_type进⾏集中认证和授权,从⽽获得access_token(访问令牌),⽽这个token是受其他微服务信任
2022-02-15 16:46:21 1345
原创 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 1229
原创 垃圾收集器
垃圾收集器可以分为串行收集器(新生代串行收集器Serial,老年代串行收集器 Serial Old),并行收集器(新生代ParNew收集器,新生代ParallelGC收集器,老年代ParallelGC收集器),CMS收集器,G1收集器串行收集器(Serial):串行垃圾回收是为单线程环境设计且只使用一个线程进行垃圾回收,会暂停所有的用户线程。并行收集器:多个垃圾收集器线程并行工作,同样会暂停用户线程。CMS收集器:用户线程和垃圾回收线程同时执行,不一定是并行的,可能是交替执行,可能一边垃圾回收,一边运
2021-12-14 16:20:12 500
原创 垃圾收集算法
垃圾收集可以分为部分收集和整堆收集部分收集包括新生代收集(Minor GC/Young GC),老年代收集(Major GC/Old GC)如CMS收集器,混合收集(Mixed GC)如有G1收集器整堆收集(Full GC)即 收集整个Java堆和方法区的垃圾收集标记-清除算法标记-清除算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以反过来,标记存活的对象,统一回收所有未被标记的对象。标记-清除算法有两个不足之处:第一个是执行
2021-11-30 20:42:10 105
原创 引用计数法和可达性分析算法
垃圾回收的区域:方法区,堆引用计数法栈中有对堆中的对象有引用,如果失去了这个引用关系,那么这个对象就需要被回收在引用计数法中当一个对象被引用时,这个对象的的计数值+1,失去引用时,计数值-1,当计数值为0时表示对象需要被回收,但是引用计数法无法检测循环引用。循环引用:有AB对象,这两个对象互相引用,除了这个互相引用没有地方在使用这两个对象,所以这两个对象时应该是要被回收,但是因为它们的引用计数都是1,无法被回收可达性分析算法可达性分析算法:从GC root 出发,向下开始搜索引用的对象,搜索经
2021-11-29 16:00:28 360
原创 类加载器的类型
类的加载阶段将类的.class文件中的二进制数据读入到内存中,将其常量池、属性表、方法表、异常表放在运行时数据区的方法区内,然后在创建一个对应的java.lang.Class对象,用来封装类在方法区内的数据结构JVM主要在程序第一次主动使用类的时候,才会去加载该类,而且只加载一次jvm支持两种类型的加载器,分别是引导类加载器()和自定义加载器,引导类加载器是由c/c++实现的,自定义加载器是由java实现的。自定义加载器相当于ClassLoader的子类,它包括扩展类加载器(Extension Clas
2021-11-22 20:20:45 575
原创 类加载的执行过程
代码经过编译后成为了.class文件,类加载子系统负责从文件系统中或是网络中加载.class文件,加载后的class类信息放在方法区,类加载器只负责加载,是否运行由执行引擎决定加载预加载虚拟机启动的时候会加载JAVA_HOME/lib/rt.jar中的.class文件例如java.lang.*,java.util*,java.io.*等...
2021-11-10 22:10:06 2139
原创 栈溢出的原因
栈的大小用-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 322
原创 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 165
原创 jvm运行时内存
jdk7中的内存结构jdk8中的内存结构线程私有的:程序计数器,虚拟机栈,本地方法栈线程共享的:堆,方法区,元空间,直接内存java8之后方法区的变化:元空间替换永久代,永久代中的类原信息转移到了本地内存,字符串常量池和静态变量转移到了堆程序计数器程序计数器是当前线程字节码的行号提示器,在字节码解释器工作的时候改变程序计数器的值来选取下一条将要执行的字节码指令。分支、循环、跳转、异常、线程恢复等都靠这个程序计数器完成。一个cpu同一时间只能执行一个cpu中的命令,线程未执行完的命令,会保
2021-10-29 22:37:44 628 5
原创 CompletableFuture的使用和部分原理
CompletableFuture是一个异步编程工具类简单使用 CompletableFuture<String> completableFuture = new CompletableFuture<>(); new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) {
2021-10-19 22:36:55 470
原创 ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor可以按时间来执行任务,它继承了ThreadPoolExecutor构造方法 public ScheduledThreadPoolExecutor(int corePoolSize) { //使用ThreadPoolExecutor的构造方法 //DelayedWorkQueue是ScheduledThreadPoolExecutor内部自己实现的阻塞队列 super(corePoolSize, Integer
2021-10-10 18:58:48 126
原创 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 112
原创 读写锁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 126
原创 AtomicIntegerFieldUpdater
如果一个类是自己编写的,则可以在编写的时候把成员变量定义为Atomic类型。但如果是一个已经有的类,在不能更改其源代码的情况下,要想实现对其成员变量的原子操作,就需要AtomicIntegerFieldUpdater、AtomicLongFieldUpdater 和 AtomicReferenceFieldUpdater。AtomicIntegerFieldUpdater的使用 public static void main(String[] args) { Student stu
2021-09-13 18:29:54 1343
原创 AtomicStampedReference
AtomicInteger,AtomicBoolean,AtomicReference都是根据value的是否变化来做cas修改的,但是这样无法解决ABA的问题AtomicStampedReference类不仅比较了对象还比较了版本号AtomicStampedReference的使用 Object obj = new Object(); int initialStamp = 0; AtomicStampedReference atomicStampedRe
2021-09-10 14:55:58 435
原创 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 113
原创 同步工具类 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 98
原创 同步工具类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 80
原创 同步工具类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 59
原创 同步工具类Semaphore
Semaphore提供了资源数量的并发访问控制,也就是线程的并发量代码使用//一开始有5份共享资源,即5个线程并发量。第二个参数表示是否是公平Semaphore semaphore = new Semaphore(5,true);// 工作线程每获取一份资源,就在该对象上记下来// 在获取的时候是按照公平的方式还是非公平的方式,要看上面代码的第二个参数是否公平。 // 一般非公平抢占效率较高。semaphore.acquire();// 工作线程每归还一份资源,就在该对象上记下来 //
2021-09-02 18:09:47 86
原创 ConcurrentHashMap
ConcurrentHashMap由数组+链表+红黑树组成数组中存放的是链表的头结点,或者红黑树的根节点如果头节点是Node类型,它后面的的就是一个普通的链表;如果头节点是TreeNode类型,它的后面就是一颗红黑树,TreeNode是Node的子类链表和红黑树之间可以相互转换:初始的时候是链表,当链表中的元素超过某个阈值时,把链表转换成红黑树;当红黑树中的元素个数小于某个阈值时,再转换为链表。构造方法 public ConcurrentHashMap(int initialCapacit
2021-08-31 22:30:33 91
原创 ConcurrentLinkedQueue
ConcurrentLinkedQueueConcurrentLinkedQueue 的实现原理和AQS内部的阻塞队列类似,AQS是基于双向链表,通过对head/tail进行CAS操作,实现入队和出队,队列里面放的是线程,而ConcurrentLinkedQueue是一个单向链表,里面放的是实际的元素public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> implementsQueue<E>, j
2021-08-24 23:33:39 143
原创 CopyOnWriteArrayList
CopyOnWrite指在“写”的时候,不是直接“写”源数据,而是把数据拷贝一份进行修改,再通过悲观 锁或者乐观锁的方式写回。拷贝一份修改是为了在“读”的时候不加锁CopyOnWriteArrayListCopyOnWriteArrayList的核心数据结构是一个数组 arraypublic class CopyOnWriteArrayList<E> implements List<E>, RandomAccess,Cloneable, java.io.Serializab
2021-08-23 22:31:55 97
原创 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 77
原创 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 151
原创 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 3792
原创 PriorityBlockingQueue和DelayQueue
PriorityBlockingQueuePriorityQueue(优先级阻塞队列)是按照元素的优先级从小到大出队列的。正因为如此, PriorityQueue元素之间需要可以比较大小(使用PriorityBlockingQueue的Comparator,或者元素实现Comparable)。public class PriorityBlockingQueue<E> extends AbstractQueue<E> implementsBlockingQueue<E>
2021-08-05 23:40:05 157
原创 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 275
原创 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 210
原创 优雅的关闭线程
在Java中,有stop()、destory()等方法,但这些方法官方明确不建议使用。原因很简单,如果强制杀死线程,则线程中所使用的资源,例如文件描述符、网络连接等无法正常关闭。可以使用标志位关闭循环线程代码实现public class MyThread extends Thread { //声明一个停止标志位 private boolean running = true; @Override public void run() { while (ru
2021-08-01 23:55:27 136
原创 线程的interrupt
InterruptedException异常:声明了抛出InterruptedException异常的方法(轻量级阻塞的方法),线程在阻塞时,其他线程(比如主线程)调用这个线程的interrupt()方法,阻塞线程会抛出InterruptedException异常并从阻塞状态中跳出。声明了InterruptedException的方法有public static native void sleep(long millis) throws InterruptedException{//...}publ
2021-07-31 00:51:02 154
原创 使用wait notify实现生产者消费者模型
一个内存队列,多个生产者线程往内存队列中放数据;多个消费者线程从内存队列中取数据使用wait()与notify()机制队列的实现public class MyQueue { /** * 数组队列(总长度为10) */ private String[] data = new String[10]; /** * 出队列的下标 */ private int getIndex = 0; /** * 入队列的下标
2021-07-28 00:37:38 215
原创 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 81 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 115 1
原创 并发编程基础
并发编程三要素原子性:即一个不可再被分割的颗粒。在Java中原子性指的是一个或多个操作要么全部执行成功要么全部执行失败。有序性:程序执行的顺序按照代码的先后顺序执行。(处理器可能会对指令进行重排序)可见性:当多个线程访问同一个变量时,如果其中一个线程对其作了修改,其他线程能立即获取到最新的值(处理本地缓存)。线程的五大状态创建状态:当用new操作符创建一个线程的时候就绪状态:调用start方法,处于就绪状态的线程并不一定马上就会执行run方法,还需要等待CPU的调度运行状态:CPU开始调度线程
2021-07-19 00:10:33 128
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人