自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Tomcat启动流程

tomcat的启动一般是走脚本启动,但是最终还是在org.apache.catalina.startup.Bootstrap类的main方法启动的。从main方法中的init(),load(),start()。就能看出tomcat在启动的时候,对于每个组件是怎么加载的。

2023-07-03 23:05:56 444

原创 Tomcat生命周期

tomcat中包含了很多组件:Server、Connector、Service、Engine、Host、Context等等这些组件的生命周期是怎么样设计的呢?

2023-07-03 22:44:11 165

原创 Tomcat简介

Servlet是JavaEE中的规范,定义很多接口,Servlet接口、HttpRequest接口、HttpResponse接口等,在由不同的服务厂商来实现比如tomcat、jetty对应的服务器容器接受到HTTP请求,然后解析这个请求创建Servlet实例,调用init方法初始化将请求相关的信息封装成ServletRequest调用service方法来执行通过ServletResponse封装响应给容器,最后返回给客户端。

2023-07-03 22:19:31 128

原创 一、Java-基础知识

利用抽象的数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体。数据被保护在抽象数据类型的内部,尽可能的隐藏内部的细节,只保留一些对外接口使其与外部发生联系。用户无需知道对象内部的细节,但是可以通过对象对外提供的接口来访问对象。优点以下 Person 类封装 name、gender、age 等属性,外界只能通过 get() 方法获取一个 Person 对象的 name 属性和 gender 属性,而无法获取 age 属性,但是 age 属性可以供 work() 方法使用。

2023-06-01 23:15:32 99

原创 十六、DelayQueue

入队:入队只有一个方法,就是offer,因为DelayQueue是无界队列,所以生产者是不需要阻塞的出队poll:直接拿堆顶数据,堆顶的延迟时间到了,直接返回任务,如果没到时间,返回null。直接拿堆顶数据如果为null,或者阻塞时间已经到了,直接告辞!如果不为null并且延迟时间到了,返回数据如果数据时间没到,查看阻塞剩余的时间到了么,到了直接返回null如果数据的延迟时间没到如果阻塞时间小于延迟时间,或者已经有leader了,直接等待阻塞时间,等待被唤醒即可。

2023-06-01 22:24:11 75

原创 十五、PriorityBlockingQueue

offer获取到锁首先判断是否需要扩容扩容:并发执行的(单独一个CAS操作保证只有一个线程执行),因为扩容的第一步就是释放锁。看长度是不是64,小于扩容2倍,大于则扩容1.5倍小顶堆(默认)/自定义比较器,来实现插入size+1唤醒读线程(Condition读)释放锁poll获取到锁判断是否有数据,没有直接返回null小顶堆(默认)/自定义比较器,来实现获取size-1释放锁获取到锁判断是否有数据,没有则。

2023-05-31 23:03:49 76

原创 十四、LinkedBlockingQueue

千万不要有一个想法:如果读和写在同一个Node咋办这是不可能的,一定是写了一个Node,才会有读的线程去消费。

2023-05-31 22:44:07 146

原创 十三、ArrayBlockingQueue

ArrayBlockingQueue其实就是用ReentrantLock+2个condition实现的生产消费队列啊。offer/polloffer:先看队列中的count跟items.length是否相等,如果相等,则返回false。不等则插入poll:先看队列中的count==0,如果相等,则返回null。如果不等则返回数据呗offer:先看队列中的count跟items.length是否相等如果相等,则阻塞timeout时间,然后在唤醒,尝试一下。如果失败了就false。

2023-05-31 22:27:14 114

原创 十二、CyclicBarrier

线程执行await方法,会对count-1,再判断count是否为0如果不为0,需要添加到AQS中的ConditionObject的Waiter队列中排队,并park当前线程如果为0,证明线程到齐,需要执行nextGeneration,会先将Waiter队列中的Node全部转移到AQS的队列中,并且有后继节点的,ws设置为-1。没有后继节点设置为0。然后重置count和broker标记。等到unlock执行后,每个线程都会被唤醒。

2023-05-31 22:15:33 49

原创 十一、Semaphore

首先判断当前信号量是公平还是非公平公平:判断当前线程是不是head的next,如果不是则直接返回-1;如果是则CAS尝试获取资源,修改state,返回state-acquires的值非公平:CAS尝试获取资源,修改state,返回state-acquires的值如果没有获取到资源则构建SHARD节点,然后判断这个节点是不是head的next:如果是话:那么就唤醒所有的阻塞线程,如果遇到头结点为0的时候,那么就将头节点状态变为-3如果不是:那么就阻塞当前线程(放在-1节点的后面)

2023-05-31 22:12:40 52

原创 十、CountDownLatch

await方法:先看state是不是0:如果是0则直接放行,不阻塞如果不是0,则构建SHARD节点,然后判断这个节点是不是head的next:如果是话:那么就唤醒所有的阻塞线程如果不是:那么就阻塞当前线程(放在-1节点的后面)countDown方法:先看state是不是0:如果是0则直接放行,不阻塞如果不是0,state-1然后CAS刷新state。然后判断state == 0如果是0,则唤醒队列中的阻塞线程。

2023-05-31 22:06:17 77

原创 九、ConcurrentHashMap

ConcurrentHashMap中将节点的状态分为:-1moved、-2红黑树、-3占位、0正常首先用key的hash值算出一个hash来,主要让key的hash高16位参与运算,这样更散列,防止hash冲突判断数组是不是null/长度等于0,因为ConcurrentHashMap是懒加载用1中算出来的hash值,与数组长度-1计算,得出index判断当前位置是不是null,如果是的话就是CAS插入了。

2023-05-31 00:51:08 3156

原创 八、ThreadPoolExcuter

当一个任务提交至线程池之后:线程池首先判断当前运行的线程数量是否少于corePoolSize。如果是,则创建一个新的工作线程来执行任务。如果都在执行任务,则判断BlockingQueue是否已经满了,倘若还没有满,则将线程放入BlockingQueue。如果创建一个新的工作线程将使当前运行的线程数量超过maximumPoolSize,则交给RejectedExecutionHandler来处理任务。

2023-05-31 00:42:22 74

原创 七、ReentrantReadWriteLock

tryAcquire判断是不是写锁的重入锁 ,如果是的话,就直接state+1,抢锁成功了判断还能不能抢一次锁:公平锁调用hasQueuedPredecessors方法,非公平锁则直接抢抢锁失败则调用addWaiter和acquireQueued方法,跟ReentrantLock一样的。

2023-05-31 00:29:38 95

原创 六、ReentrantLock

备注:抢锁的逻辑都是执行一次cas非公平锁上来先抢一把,公平锁不会抢。(ReentrantLock中的Sync类中的lock方法)尝试抢锁(AQS中的tryAcquire方法)公平锁:拿到当前线程以及AQS锁状态当state==0时,判断队列是不是空,空的话抢锁。非空的话需要去看一下head的next是不是当前线程,如果是也去抢锁。当state!=0时,判断当前线程,是不是拿锁的线程,如果是话,就重入拿锁啊。非公平锁:拿到当前线程以及AQS锁状态当state==0时,直接去抢一次锁。

2023-05-31 00:14:49 91

原创 五、Synchronized

Synchronized锁就是基于对象实现的,只不过分为class对象和其他。

2023-05-30 23:58:50 71

原创 四、Java-锁基本概念

锁分类可重入锁、不可重入锁可重入锁:某个线程获得了A锁后,如果A锁里面的代码还需要继续获得A锁,那么就可以获得继续执行。举例:synchronized、ReentrantLock、ReentrantReadWriteLock不可重入锁:某个线程获得了A锁后,如果A锁里面的代码还需要继续获得A锁,那么就不能获得,直接死锁了。当前Java就只有一个地方有,线程池源码里面的Wroker类是的。乐观锁、悲观锁乐观锁:当前线程不能获取锁资源,可以让cpu继续获取锁资源。举例:CAS(Atomic)

2023-05-30 23:47:56 39

原创 三、并发的三大特性

synchronized在保证可见性:在获取锁的瞬间,将内部涉及的变量从CPU缓存中清除掉,然后从主存重新获取。其实Lock锁的底层也是通过volatile实现的,因为lock锁的底层每次在lock/unlock的时候都要操作一个volatile变量state。就是在你操作的时候,用平常把操作隔开,禁止你重排序。这个就有点牵强了,因为final修饰的变量,在编译时就已经确定了,不会在改变了,肯定保证了所谓的可见性啊。简单的说:在单线程的情况下,指令重排可以的,但是最终结果要保持不变。

2023-05-30 00:08:30 350

原创 二、Java-线程

1~10,10最大。这个优先级,不是绝对的。只能说会影响cpu的调度。后面设置的名字,会覆盖初始化。

2023-05-29 23:50:04 65

原创 一、基础概念

一、进程与线程进程与线程进程指运行中的程序线程是CPU的基本调度单位,每个线程执行的都是某一个进程代码中的片段进程就是线程的“容器”,一个进程起码有一个线程。进程与线程的区别根本不同:进程是操作系统分配的资源,线程是CPU调度的基本单元资源方面:不同进程之间资源不共享。同一个进程下,线程是共享进程资源的。线程有自己独立的存储空间,这个是在cpu里面的,缓存么。数量不同:进程一般就指一个进程,一个进程拥有一个或者多个线程开销不同:线程的创建、终止、切换很快,进程做这些操作的时候很慢

2023-05-29 23:34:11 78

原创 四、Java-Set

底层用红黑树存放数据。

2023-05-29 23:29:53 36

原创 三、Java-List

基于ArrayList的。

2023-05-29 23:22:48 59

原创 二、Java-Map

哈希表 = 数组 + 链表。

2023-05-29 23:17:11 48

原创 一、基本知识

是一个假的copy,是将list2里面的数据,对list1进行覆盖。list2的数据还不能比list1多,因为多出来的没有办法覆盖了。可以看到,其实就是将所有的方法加上了Synchronized锁。其实也是将所有的方法添加了Synchronized锁。将这个集合中的所有元素替换。返回并且移除最后一个元素。

2023-05-29 23:08:54 42

原创 十五、调优工具

位于jdk的bin目录下。

2023-05-29 22:48:00 62

原创 十四、JVM优化(运行期优化)

对象逃逸的本质是对象指针逃逸如果一个对象的指针被多个方法或者线程引用,那么就称之为“对象逃逸”主要是有效的减少java程序中同步负载和内存堆分配压力的一个算法。通过这个分析,就能知道一个新对象是否要分配到堆内。逃逸分析不是优化手段,而是代码分析手段举例:jdk1.8以后是默认开起逃逸分析的。

2023-05-29 22:44:09 65

原创 十三、JVM优化(编译期优化)

一、编译期优化(执行引擎)二、JVM执行引擎编译器将.java文件编译成.class文件,然后交给JVM运行,JVM只认识.class文件。所以很多语言只要能编译成.class文件就能运行,且还能在不同的操作系统上运行最终将.class文件转化成机器码,其实就是00101010这种玩意,然后机器才能运行,那么这个步骤就是执行引擎干的活JVM采用的是混合执行模式(默认的,当然你也可以指定用哪一种,看你自己的业务了)解释执行器Interpreter,将字节码(.class)逐行翻译成机器码

2023-05-29 22:37:25 68

原创 十二、JVM命令

一、jps查看java进程The jps command lists the instrumented Java HotSpot VMs on the target system.The command is limited to reporting information on JVMs for which it has the access permissions二、jinfo实时查看和调整JVM配置参数The jinfo command prints Java configurat

2023-05-25 23:18:24 58

原创 十一、ZGC垃圾回收器

Xlog:safepoint,classhisto*=trace,age*,gc*=info:file=/opt/logs/logs/gc-%t.log:time,tid,tags:filecount=5,filesize=50m 设置GC日志中的内容、格式、位置以及每个日志的大小。调大后GC变快,但会占用程序运行时的CPU资源,吞吐会受到影响。-XX:+UnlockDiagnosticVMOptions -XX:-ZProactive 是否启用主动回收,默认开启,这里的配置表示关闭。

2023-05-25 23:10:59 131

原创 十、G1垃圾回收器

Region可以继续细分的:HHR(大对象区:当一个对象大小超过Region的1.5倍时):大对象头分区、大对象连续区老年代分区:Old Generation在jdk11后,还有归档区(关闭归档区,开启归档区),用的是堆外内存Region总共2048个,大小1~32M。为什么都是2的N次幂?2的N次在位运算的时候效率是最高的。

2023-05-25 23:03:32 744 1

原创 九、CMS

第三种情况:2C4G,这种情况下,也不推荐使用,因为2C的情况下,线程上下文的开销比较大,性能可能还不如你不动的情况,没必要。CPU核心数 <= 8,则为 ParallelGCThreads=CPU核心数,比如4C8G取4,8C16G取8。CPU核心数 > 8,则为 ParallelGCThreads = CPU核心数 * 5/8 + 3 向下取整。ParallelGCThreads = 13~16时,ConcGCThreads = 4。16核的情况下,ParallelGCThreads = 13。

2023-05-25 22:47:32 421 1

原创 八、JVM参数

不会随着java版本更新而改变。

2023-05-25 22:30:14 84 1

原创 七、垃圾收集器

垃圾回收算法只是“方法论”,垃圾收集器才是具体的实现。

2023-05-25 22:24:30 95 1

原创 六、垃圾回收算法

其实标记整理应该叫做标记-清除-整理,因为它是先标记,在清除,最后整理的。

2023-05-25 22:12:50 108 1

原创 五、Java对象内的布局

Xss:设置栈的大小(1.5以后,栈的大小默认是1M,也就是说,开启一个线程默认就需要1M的资源)-XX:MaxMetaspaceSize=50M 最大方法区大小。-XX:MetaspaceSize=50M 初始化方法区大小。finalize很多三方件有实现,比如图片缓存,会导致内存泄漏。-Xms:初始堆大小。-Xmx:最大堆大小。

2023-05-25 21:59:52 242 1

原创 四、JAVA MEMORY MODEL

读取数据的时候,从L0->L6,找到的后,然后依次往上放。最后就是从寄存器、L1里面拿数据了,一个字快。

2023-05-24 20:25:46 120 1

原创 三、Class加载过程

如果以上三个条件全部满足,jvm就会在方法区垃圾回收的时候对类进行卸载,类的卸载过程其实就是在方法区中清空类信息,java类的整个生命周期就结束了。一般情况下启动类加载器加载的类不会被卸载,而我们的其他两种基础类型的类加载器只有在极少数情况下才会被卸载。

2023-05-17 22:31:06 292

原创 二、Class文件

其实通过IDEA去看一个class文件,能看出一个java类中所有的东西(构造方法,方法,属性等等,还有方法之间的调用关系等),比较重要的就是Class文件中包含了一个常量池,在编译期间就能确定很多东西。如上图:基本上所有的java代码转化成16进制,开头都是 “CA FE BA BE”,其实就是 Magic Number。通常我们看的都是16进制的,二进制没啥看的都是0和1。常量池:将我们的class文件翻译存储在常量池里面,方便以后使用。用来判断当前java文件的修饰符是啥。当前类实现的接口数量。

2023-05-16 23:54:50 130

原创 一、JVM基础知识(Java)

区别:JIT编译器比解释器模式在代码运行上要快很多,但是启动的时候就要慢,因为你要将热点代码全部编译。模式二:JIT编译器:将热点代码先全部编译成本地代码,然后执行。当前常见的JVM都是用的混合模式,解释器+JIT编译器。模式一:解释器:编译一行代码,执行一行代码。

2023-05-16 22:59:35 58 1

空空如也

空空如也

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

TA关注的人

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