自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 ConcurrentLinkedQueue

非阻塞队列中的几种主要方法:offer(E e):将元素e插入到队列末尾,如果插入成功,则返回true;如果插入失败(即队列已满),则返回false;poll():移除并获取队首元素,若成功,则返回队首元素;否则返回null;peek():获取队首元素,若成功,则返回队首元素;否则返回null对于非阻塞队列,对于非阻塞队列,一般情况下建议使用offer、poll和peek三个方法,不建议使用add和remove方法。

2023-11-30 10:38:17 393

原创 ConcurrentHashMap

concurrentHashMap是一个支持高并发更新与查询的哈希表(基于HashMap)。hashtable该类不依赖于synchronization去保证线程操作的安全。Collections.synchronizedMap()也可以将map转成线程安全的。而concurrentHashMap在保证安全的前提下,进行get不需要锁定。ConcurrentHashMap的主要使用CAS 加 volatile 或者 synchronized 的方式来保证线程安全。

2023-11-30 10:35:47 755

原创 Set相关类

HashSet 基于 HashMap 实现。放入HashSet中的元素实际上由HashMap的key来保存,而HashMap的value则存储了一个静态的Object对象。底层源码。

2023-11-30 10:35:01 444

原创 TreeMap & 红黑树

由于在AVL树中,由于AVL树是绝对平衡的,所有在进行插入和删除的时候,为了维护其绝对的平衡性,有时候进行修改节点的操作,需要进行到根节点,旋转的次数比较多,所以出现了红黑树,当数据不是静态的数据而是动态的数据,进行插入和删除的时候就不用去维护绝对的平衡,也就减少了旋转的次数,照样可以提高效率,并且红黑树的平均查找效率还是logn。我们没有考虑叔叔节点是黑节点情况,因为如果叔叔结点为黑结点,而父结点为红结点,那么叔叔结点所在的子树的黑色结点就比父结点所在子树的多了,这不满足红黑树的性质5。

2023-11-30 10:34:10 873

原创 HashMap详解

/ HashMap的默认初始容量,16//HashMap的最大支持容量,2^30//HashMap的默认加载因子//Bucket中链表长度大于该默认值,转化为红黑树//Bucket中红黑树存储的Node小于该默认值,转化为链表/*** 桶中的Node被树化时最小的hash表容量。*(当桶中Node的数量大到需要变红黑树时,* 若hash表容量小于MIN_TREEIFY_CAPACITY时,

2023-11-30 10:33:10 846

原创 自定义类加载器加载java.lang.String?

写了个java.lang.ClassLoader,把preDefineClass()方法里那段if直接删掉,再用编译后的class替换rt.jar里面的,直接通过命令jar uvf rt.jar java/lang/ClassLoader/class即可。加载同一个类MyClassLoader,使用的类加载器不同,说明这里是打破了双亲委派机制的,但是尝试加载String类的时候报错了。那么既然是ClassLoader里面的代码做的限制,那把ClassLoader.class修改了不就好了吗。

2023-11-06 10:53:47 64

原创 JVM调优

这里的吞吐量是指应用程序所花费的时间和系统总运行时间的比值。我们可以按照这个公式来计算 GC 的吞吐量:系统总运行时间 = 应用程序耗时 +GC 耗时。如果系统运行了 100 分钟,GC 耗时 1 分钟,则系统吞吐量为 99%。GC 的吞吐量一般不能低于95%:指垃圾收集器正在运行时,应用程序的暂停时间。对于串行回收器而言,停顿时间可能会比较长;而使用并发回收器,由于垃圾收集器和应用程序交替运行,程序的停顿时间就会变短,但其效率很可能不如独占垃圾收集器,系统的吞吐量也很可能会降低。

2023-11-06 10:53:00 31

原创 自定义一个String类

可以自定义包名不为java.lang的String类,并区别包名正常使用自定义包名为java.lang的String类String类下写main方法:由于双亲委派模型,在加载String类时,会最终委派给Bootstrap ClassLoader去加载,加载的是rt.jar包中的那个java.lang.String,而rt.jar包中的String类是没有main方法的,因此报错误。

2023-11-06 10:52:20 246

原创 类的加载和加载器

类的加载过程:加载:将java文件加载为字节码class文件验证:确保Class文件的字节流中包含的信息符合JVM规范准备:为 static 变量分配空间,设置默认值解析:将常量池内的符号引用替换为直接引用初始化:执行类构造器JDK中有三个默认类加载器:AppClassLoader、ExtClassLoader、BootStrapClassLoader。

2023-11-06 10:51:36 32

原创 G1收集器 - 垃圾回收器(GC)

JDK 9以后默认使用,替代了CMS 收集器。

2023-11-06 10:48:19 117

原创 垃圾回收(GC)器

指多条垃圾收集线程并行工作,但此时用户线程仍处于等待状态。指用户线程与垃圾收集线程同时工作(不一定是并行的可能会交替执行)。用户程序在继续运行,而垃圾收集程序运行在另一个CPU上即CPU用于运行用户代码的时间与CPU总消耗时间的比值(吞吐量 = 运行用户代码时间 / ( 运行用户代码时间 + 垃圾收集时间 )),也就是。例如:虚拟机共运行100分钟,垃圾收集器花掉1分钟,那么吞吐量就是99%

2023-11-06 10:47:48 22

原创 GC(垃圾回收)算法

GC( Garbage Collection ),垃圾回收,是Java与C++的主要区别之一。作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码。这是因为在Java虚拟机中,存在自动内存管理和垃圾清理机制。对JVM中的内存进行标记,并确定哪些内存需要回收,根据一定的回收策略,自动的回收内存,保证JVM中的内存空间,防止出现内存泄露和溢出问题。finalize()是Object的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法。

2023-11-06 10:47:12 52

原创 常量(StringTable)池

二进制字节码的组成:类的基本信息(构造方法,接口的定义)、常量池、静态变量、类的方法定义(包含了虚拟机指令)通过反编译来查看类的信息(框内的是真正编译执行的内容,#号的内容需要在常量池中查找)

2023-11-06 10:46:02 24

原创 JVM 虚拟机

线程私有的,作为当前线程的行号指示器,用于记录当前虚拟机正在执行的线程指令地址。每个线程运行需要的内存空间,称为虚拟机栈每个栈由多个栈帧组成,对应着每次调用方法时所占用的内存每个线程只能有一个活动栈帧,对应着当前正在执行的方法Java 虚拟机栈是由一个个栈帧组成,栈顶存放当前方法,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。每一次函数调用都会有一个对应的栈帧被压入虚拟机栈,每一个函数调用结束后,都会有一个栈帧被弹出。

2023-11-06 10:45:11 37

原创 强软弱虚四种引用

Java 程序通过栈上的 reference 数据来操作堆上的具体对象。

2023-11-06 10:44:04 130

原创 ArrayList详解、Vector和CopyOnWriteArrayList和LinkedList

/集合默认容量10;//空数组//默认容量的空的数组// 集合中真实存储数据的数组//集合中元素的个数,注意,这里不是数组的长度对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高;底层使用双向链表存储//存储链表的第一个节点//存储链表的最后一个节点。

2023-10-14 09:31:05 82

原创 手写生产者消费者模型、阻塞队列

【代码】手写生产者消费者模型、阻塞队列。

2023-10-14 09:29:42 69

原创 多线程交替打印ABC的多种方式

【代码】多线程交替打印ABC的多种方式。

2023-10-14 09:29:07 93

原创 ReadWriteLock和StampedLock

ReadWriteLock 和 StampedLock 都是Java中用于并发控制的重要机制。ReadWriteLock 适用于读多写少的场景;StampedLock 则适用于读远远大于写的场景,并且对数据的一致性要求不高;在实际应用中,我们需要根据具体场景来选择合适的锁机制。通过合理使用这些锁机制,我们可以提高并发程序的性能和可靠性。

2023-10-07 09:54:03 25

原创 简单说说CAS

CAS可以将比较和交换转换为原子操作,这个原子操作直接由处理器保证(由CPU支持),会拿旧的预估值与内存当中的最新值进行比较;如果相同就进行交换并且把最新的值赋值到内存当中的这个变量;CAS 必须借助 volatile 才能读取到共享变量的最新值来实现【比较并交换】的效果。使用CAS时,线程数不要超过CPU的核心数,每个CPU核心都能同时并行某个线程,超过的话想运行也运行不了,得发生上下文切换。线程的上下文切换的成本很高,要保存线程的信息,当从阻塞恢复成可运行,还要恢复线程的信息。

2023-10-07 09:00:12 28

原创 原子类AtomicInteger

改为原子类。

2023-10-07 08:57:51 47

原创 并发工具类

在JDK的并发包里提供了几个非常有用的并发工具类。CountDownLatch、CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段。

2023-10-07 08:56:03 18

原创 Java创建线程的几种方式

Java使用Thread类代表线程,所有线程对象都必须是Thread类或者其子类的实例。

2023-10-07 08:53:52 35

原创 ThreadLocal底层原理

线程本地变量。当使用 ThreadLocal 维护变量时, ThreadLocal 为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程。每个线程都有一个 ThreadLocalMap ( ThreadLocal 内部类),Map中元素的,而值对应线程的变量副本。

2023-10-07 08:52:23 25

原创 如何停止一个线程

stop 方法虽然可以停止线程,但它已经是不建议使用的废弃方法了,这一点可以通过 Thread 类中的源码发现,stop 源码如下:stop 方法是被 @Deprecated 修饰的不建议使用的过期方法,并且在注释的第一句话就说明了 stop 方法为非安全的方法。原因在于它在终止一个线程时会强制中断线程的执行,不管run方法是否执行完了,并且还会释放这个线程所持有的所有的锁对象。这一现象会被其它因为请求锁而阻塞的线程看到,使他们继续向下执行。这就会造成数据的不一致。

2023-10-07 08:51:05 17

原创 并发编程中的三个问题

可见性:是指当一个线程对共享变量进行了修改,那么另外的线程可以立即看到修改后的最新值。案例演示:一个线程A根据 boolean 类型的标记 flag,while死循环;另一个线程B改变这个flag变量的值;那么线程A并不会停止循环。解决可见性:Ⅰ. 在共享变量前面加上关键字修饰;Q:为什么volatile关键字能保证可见性?

2023-09-27 11:18:24 22

原创 synchronized和ReentrantLock

指的是 同一个线程的 可以多次获得 同一把锁(一个线程可以多次执行synchronized,重复获取同一把锁)。

2023-09-27 11:17:51 18

原创 AQS详解

AQS ( Abstract Queued Synchronizer )是一个抽象的队列同步器,通过维护一个共享资源状态( Volatile Int State )来表示同步状态 和一个先进先出( FIFO )的线程来完成资源获取的排队工作,通过CAS完成对State值的修改。AQS整体框架如下:当有自定义同步器接入时,只需重写第一层所需要的部分方法即可,不需要关注底层具体的实现流程。

2023-09-27 11:11:36 94

原创 简单说说volatile

volatile是轻量级的同步机制,volatile可以用来解决可见性和有序性问题,但不保证原子性。

2023-09-27 11:05:38 44

原创 Java内存模型JMM

java内存模型(即 java Memory Model,简称JMM),不存在的东西,是一个概念,约定主要分成两部分来看,一部分叫做主内存,另一部分叫做工作内存。JMM的同步约定:主要目的就是在多线程对共享变量进行读写时,来保证共享变量的可见性、有序性、原子性;在编程当中是通过两个关键字 synchronized 和 volatile 来保证共享变量的三个特性的。一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存的呢?Java内存模型中定义了上图中的 8 种操作(橙色箭头)来完成,虚拟机实现时必

2023-09-27 11:04:53 19

原创 CPU的缓存一致性

CPU 在读写数据的时候,都是在 CPU Cache 读写数据的,原因是 Cache 离 CPU 很近,读写性能相比内存高出很多。对于 Cache 里没有缓存 CPU 所需要读取的数据的这种情况,CPU 则会从内存读取数据,并将数据缓存到 Cache 里面,最后 CPU 再从 Cache 读取数据。写直达,只要有数据写入,都会直接把数据写入到内存里面,这种方式简单直观,但是性能就会受限于内存的访问速度;

2023-09-27 11:02:41 47

原创 手写线程池

首先,定义一个线程池接口,用来表示线程池应该具备哪些功能。添加任务并执行关闭线程池强制关闭线程池//提交任务到线程池中 void execute(Runnable task);//优雅关闭线程 void shutdown();//立即关闭 List < Runnable > shutdownNow();//提交任务到线程池中 void execute(Runnable task);//优雅关闭线程 void shutdown();

2023-09-26 08:27:50 23 1

原创 Java中的线程池

降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。提高响应速度。当任务到达时,可以不需要等到线程创建就能立即执行。提高线程的可管理性。统一管理线程,避免系统创建大量同类线程而导致消耗完内存。

2023-09-26 08:26:33 26 1

原创 事务的隔离级别以及Mysql的事务

脏读:读到其他事务未提交的数据;不可重复读:读取到其它事务已提交的数据,导致前后读取的数据不一致;幻读:前后读取的记录数量不一致。事务的 ACID四大特性,原子性、一致性、隔离性、持久性;原子性、隔离性、持久性都是为了保证最终的一致性当多个事务并发执行的时候,会引发脏读、不可重复读、幻读这些问题。要解决脏读现象,就要将隔离级别升级到读已提交以上的隔离级别,要解决不可重复读现象,就要将隔离级别升级到可重复读以上的隔离级别。对于读已提交和可重复读读已提交。

2023-09-25 09:20:41 42 1

原创 Redis的事务

如果对事务的概念不理解,可以看看这篇文章。

2023-09-25 09:17:58 14 1

原创 Mysql中的锁

全局锁主要应用于做,这样在备份数据库期间,不会因为数据或表结构的更新,而出现备份文件的数据与预期的不一样。但是加上全局锁后,整个数据库都是只读状态,无法更新数据。因此,一般也不建议用全局锁进行全库逻辑备份。InnoDB支持可重复读的隔离级别,那么在备份数据库之前可以先开启事务,会先创建 Read View,然后整个事务执行期间都在用这个 Read View,而且由于 MVCC 的支持,备份期间业务依然可以对数据进行更新操作。

2023-09-25 09:12:52 18 1

原创 Java中的锁

不是具体的锁,是指看待并发同步的角度悲观锁:对于同一个数据的并发操作,悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改。Java中,synchronized关键字和Lock的实现类都是悲观锁。乐观锁:乐观锁不是真的锁,而是一种实现。乐观锁认为自己在使用数据时不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。如果这个数据没有被更新,当前线程将自己修改的数据成功写入。

2023-09-25 09:11:47 23 1

原创 Redis实现分布式锁

Redission分布式锁解决前三个问题原理可重入:利用hash结构记录线程id和重入次数可重试:利用信号量和PubSub功能来实现等待、唤醒,获取锁失败的重试机制超时续约:利用watchDog,开启一个定时任务,每隔一段时间(releaseTime/3),重置超时时间。使用multilock: 多个独立的redis节点,必须在所有节点都获取重入锁,才算获取成功;

2023-09-25 09:10:16 67 1

原创 程序幂等性

幂等性是开发当中很常见也很重要的一个需求,尤其是支付、订单等与金钱挂钩的服务,保证接口幂等性尤其重要对于下单等存在唯一主键的,可以使用“唯一主键方案”的方式实现。对于更新订单状态等相关的更新场景操作,使用“乐观锁方案”实现更为简单。类似于前端重复提交、重复下单、没有唯一ID号的场景,可以通过 Token 与 Redis 配合的“防重 Token 方案”实现更为快捷。

2023-09-25 08:59:52 55 1

原创 Java异常

在 Java 中,所有的异常都有一个共同的祖先 java.lang 包中的 Throwable 类。Throwable 类有两个重要的子类:Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获。Exception 又可以分为 Checked Exception (受检查异常,必须处理) 和 Unchecked Exception (不受检查异常,可以不处理)。Error :Error 属于程序无法处理的错误 ,不建议通过catch捕获。

2023-09-24 16:54:09 16 1

空空如也

空空如也

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

TA关注的人

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