自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 000_目录

目录

2024-08-28 10:35:00 254

原创 012_多线程编程

理解并发并行与并发最开始的时候,我们手里只有二极管,使用二极管搭建出一大堆的电路,这个电路具备一个能力:从某个地方加载一条一条指令并执行然后将数据写到某个位置。我们叫这个大电路为CPU。让CPU干活的方式就是给它一堆指令然他一条一条执行。这个时候问题来了,比如说你准备了一段代码,估计要运行一天,另外一个哥们儿也抱着一段代码想给CPU跑,预计就跑三分钟。大家都是文明人,肯定是你先跑,中间不停,另一个哥们儿等上一天。虽然这样可以,但是这种事儿一多,另一个哥们儿总有点怨言:难道不能中间停下一会会儿给我用一下?

2024-08-28 10:18:07 462

原创 011_IO体系

Java的IO流是实现输入/输出的基础,它可以方便地实现数据的输入/输出操作,在Java中把不同的输入/输出源抽象表述为"流"。流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。流有输入和输出,输入时是流从数据源流向程序。输出时是流从程序传向数据源,而数据源可以是内存,文件,网络或程序等。I/O分类IO体系是复杂的,涉及到的类的数量很多,而我们去接纳这个体系的前提就是有大局

2024-08-26 14:58:34 740

原创 051_总结

回头看看这段时间实在是感慨万千,杭州这边工作还是挺难找的,面试第一步是得先有一个面试机会,但是boss上一般都不太理人,以至于进入面试阶段的门槛都变得相当有难度。我个人认为,这些都是短暂的,百来年之后,都随风散去。一般而言,个体追求存活,在存活的方向上希望活的更加简单与舒服,快乐啊幸福啊,这种概念就会产生。之前一直想写源码分析,但是白天上班活多,到家就没什么心思看这看那,自己也比较懒,有可能也是因为这个原因现在还是一事无成。还好,后面也就想开了,与其一天天担心,一天天刷各种无聊的面试题,咱还是写点东西吧。

2024-08-16 17:04:22 394

原创 033_java.util.concurrent.ConcurrentSkipListMap

ConcurrentSkipListMap内部使用跳表的数据结构进行存储数据,其插入和查找的效率O(logn),其效率不低于红黑树,但是其原理和实现的复杂度要比红黑树简单多了。一般来说会操作链表List,就会对SkipList毫无压力。ConcurrentSkipListMap为了实现跳表,提供了三个内部类来构建这样的链表结构:Node、Index、HeadIndex。其中Node表示最底层的单链表有序节点、Index表示为基于Node的索引层,HeadIndex用来维护索引层次。

2024-08-16 16:17:14 633

原创 044_java.util.concurrent.ThreadPoolExecutor

是一个抽象类,实现 ExecutorService 接口,为其提供默认实现。AbstractExecutorService 除了实现 ExecutorService 接口外,还提供了方法,返回一个 RunnableFuture 对象,在运行的时候,它将调用底层可调用任务,作为 Future 任务,它将生成可调用的结果作为其结果,并为底层任务提供取消操作。...线程池处理复杂,但是本质上先搞明白其行为流程就能把源码看地大差不大。

2024-08-16 15:57:47 601

原创 045_java.util.concurrent.ScheduleThreadExecutrPool

理解ScheduleThreadExecutrPool需要的知识点还是比较多的,例如ThreadExecutrPool的一些行为和DeleyQueue的底层原理机制。在这个基础上理解定时任务的重复与延时概念如何实现就可以掌握ScheduleThreadExecutrPool的核心机制。重复依靠的是重复投递,也就是说执行任务之后再次将任务丢回给队列。而延时则利用队列的延时效应搞定。

2024-08-16 15:50:50 894

原创 043_java.util.concurrent.Exchange

Exchange的api很简单,但是其实现相对复杂,简单的说它模拟了类似于交易所交易的流程。可以和我做交易的B已经在了,我就叫B来如果没人交易,那就开单间等着来人交易找到人了,本来可以很快就搞定,但是就是磨磨唧唧,那就跑广场继续找人如果等在单间里面,时间很久了,干脆也继续跑广场继续找人达成交易依照上述策略进行。

2024-08-14 14:57:35 370

原创 035_java.util.concurrent.ConcurrentLinkedDeque

ConcurrentLinkedDeque使用了自旋+CAS的非阻塞算法来保证线程并发访问时的数据一致性。由于队列本身是一种双链表结构,所以虽然算法看起来很简单,但其实需要考虑各种并发的情况,实现复杂度较高,并且ConcurrentLinkedDeque不具备实时的数据一致性,实际运用中,如果需要一种线程安全的栈结构,可以使用ConcurrentLinkedDeque。

2024-08-14 14:56:48 606

原创 042_java.util.concurrent.Phaser

Phaser适用于多阶段多任务的场景,每个阶段的任务都可以控制得很细。其内部使用state变量及队列实现整个逻辑。当不是最后一个参与者到达时,会自旋或者进入队列排队来等待所有参与者完成任务。当最后一个参与者完成任务时,会唤醒队列中的线程并进入下一个阶段。

2024-08-12 21:31:19 657

原创 041_java.util.concurrent.CyclicBarrier

CyclicBarrier实现较为简单,功能上类似于CountDownLatch,只不过CyclicBarrier在每一轮控制之后可以自动重新对一组线程进行控制。

2024-08-12 20:42:17 426

原创 040_java.util.concurrent.CountDownLatch

CountDownLatch表示允许一个或多个线程等待其它线程的操作执行完毕后再执行后续的操作,其内部使用AQS的共享锁机制实现。CountDownLatch初始化的时候需要传入次数count,每次调用countDown()方法count的次数减1,减为0的时候会唤醒排队着的线程。

2024-08-12 20:41:11 539

原创 000_源码解析_目录

006_java.util.ArrayList源码解析。004_java.lang.String源码解析。001_Object源码解析。005_常见工具类源码解析。003_常见接口源码。

2024-08-09 17:00:23 393

原创 039_java.util.concurrent.Semaphore

Semaphore是信号量的意思,通常用于控制同一时刻对共享资源的访问上,也就是限流场景。其内部基于AQS共享锁实现。Semaphore初始化的时候指定许可次数,获得许可默认-1,释放则+1,在运行期间可以动态变更许可量。

2024-08-09 16:55:38 226

原创 032_java.util.concurrent.ConcurrentHashMap

ConcurrentHashMap是HashMap的线程安全版本,数据结构与HashMap一致。针对桶数据的put将会使用cas进行预先占位,存在桶数据则使用sychronized锁住。在扩容阶段,并发线程会帮助一起搬迁数据,该逻辑较为复杂。

2024-08-08 17:48:32 597

原创 034_java.util.concurrent.ConcurrentLinkedQueue

继承体系要实现一个线程安全的队列有两种方式:阻塞和非阻塞。阻塞队列无非就是锁的应用,而非阻塞则是CAS算法的应用。ConcurrentLinkedQueue是一个基于链接节点的无边界的线程安全队列,它采用FIFO原则对元素进行排序。采用“wait-free”算法(即CAS算法)来实现的。重要字段private transient volatile Node<E> head;private transient volatile Node<E> tail;private s

2024-08-08 17:44:48 861

原创 034_java.util.concurrent.ConcurrentLinkedQueue

要实现一个线程安全的队列有两种方式:阻塞和非阻塞。阻塞队列无非就是锁的应用,而非阻塞则是CAS算法的应用。ConcurrentLinkedQueue是一个基于链接节点的无边界的线程安全队列,它采用FIFO原则对元素进行排序。采用“wait-free”算法(即CAS算法)来实现的。

2024-08-08 17:44:48 567

原创 036_java.util.concurrent.locks.ReentrantLock

ReentantLock很重要的一块儿就是AQS框架,因此我们先来看看AQS大致是怎么工作的。我们这会聊了ReentrantLock,在实现上底层使用LockSupport来进行线程阻塞相关的行为。整体功能上看是可以和sycnized关键字对标的,并且支持了一些synchronized不支持的能力。ReentrantLock内存在AQS框架,在JDK内大量同步工具在使用。

2024-08-08 17:44:16 1030

原创 037_java.util.concurrent.locks.ReentrantReadWriteLock

ReentrantReadWriteLock内部分裂了读锁与写锁,可以让读线程同时访问,当写锁占用之后将阻塞读锁与写锁。其背后使用AQS进行支持。

2024-08-08 17:43:42 859

原创 038_java.util.concurrent.locks.StampedLock

StampedLock也是一种读写锁,但是它不是基于AQS实现的。相较于ReentrantReadWriteLock,StampedLock 多了一种乐观读的模式,以及读锁转化为写锁的方法。StampedLock内部存在state字段,高24位存储的是版本号,写锁的释放会增加其版本号,读锁不会,低7位存储的读锁被获取的次数,第8位存储的是写锁被获取的次数。由于第八位标记写锁是否被获取,不具备重入性质。

2024-08-08 17:43:10 597

原创 050_java.util.concurrent.atomic.Striped64

AtomicInteger可以被用来当做并发场景下的累加器,存在大量并发的时候cas有可能在空转带来性能损耗。这个时候就可以使用Striped64的子类进行处理。其内部存在base与cell数组,并发存在的时候会自动挑选Cell单元进行存储,本质上相当于平摊了并发到各个Cell上。在统计的时候会将base与Cell中的数据进行加和。

2024-08-06 14:45:24 1241

原创 049_java.util.concurrent.atomic.AtomicReference

AtomicInteger是数值对象的线程安全封装,将数值对象扩充到一般对象就可以使用AtomicReference来搞定,但是需要注意的是,使用cas处理并发问题有可能会导致ABA问题,JDK内自带两个解决这个问题的类,其本质思路都是使用版本进行控制。其中AtomicMarkableReference使用的是布尔值来控制,AtomicStampedReference则更加宽泛,使用数字作为版本号,每次进行cas更新的时候,都需要使用既有的版本号与引用进行匹配,匹配成功之后才能执行更新操作。

2024-08-05 17:37:56 274

原创 048_java.util.concurrent.atomic.AtomicIntegerFieldUpdater

AtomicIntegerFieldUpdater 是针对一个对象下的值域进行变更的原子类。与此实现类似的还有AtomicLongFieldUpdater,AtomicReferenceFieldUpdater。AtomicIntegerFieldUpdater本身是一个抽象类,因此不能进行实例化。但是它提供了实例的构造器:可以看到,AtomicIntegerFieldUpdater提供newUpdater方法,接受类与字段名作为初始化参数。最终行为执行在AtomicIntegerFieldUpdater

2024-08-05 15:42:35 250

原创 047_java.util.concurrent.atomic.AtomicIntegerArray

AtomicIntegerArray是对数组的线程安全封装,提供对数组某个位置的原子操作,底层依旧使用Unsafe类进行操作。

2024-08-05 15:42:05 142

原创 046_java.util.concurrent.atomic.AtomicInteger

AtomicInteger是Integer的进化版本,它提供在并发场合下的线程安全。其内部使用unsafe进行操作。unsafe提供大量原子化操作,配合violate关键字解决原子性问题与可见性问题。在使用上,cas配合while循环可以无锁进行变更值的操作,同样会带来cpu性能消耗的问题,需要参考场景谨慎使用。除此之外,cas可能会引发ABA问题,这个就需要其他类来解决了。

2024-08-05 15:41:15 274

原创 031_java.util.concurrent.CopyOnWriteArrayList

CopyOnWriteList是ArrayList的线程安全版本,其设计上将读写进行分离,只会对写操作进行阻塞,其内部使用ReentrantLock确保线程安全。CopyOnWriteList遇到写操作的时候都会将数据重新复制一份在此基础上进行修改最终将新拷贝的数据覆盖原来的数据。因此如果您的场景是读多写少,且数据不会很大的时候,CopyOnWriteList会很方便。

2024-08-04 15:07:39 511

原创 029_java.util.concurrent.LinkedTransferQueue

相比其他阻塞队列,在继承关系上,LinkedTransferQueue多出了TransferQueue的接口。除此之外,在底层实现上来说,其他的阻塞队列对读写操作都是锁上整个队列,在并发高的时候效率总是不太高的。虽然SynchronousQueue虽然不会锁住整个队列,但它是一个没有容量的队列。而LinkedTransferQueue结合了他们的特点,即可以像其他的BlockingQueue一样有容量又可以像SynchronousQueue一样不会锁住整个队列。

2024-08-03 15:41:17 780

原创 028_java.util.concurrent.SynchronousQueue

SynchronousQueue平时用的比较少,虽然它也是一个阻塞队列,但是特殊之处在于它实际上不存储数据,其内部不存在容器。这个类的使用场景是,一个producer线程对SynchronousQueue进行put的时候,如果consumer没有动作则producer必须阻塞等待concumer从SynchronousQueue中进行take操作。consumer执行take的时候会唤醒producer,并且或得到producer的东西。这个过程称为一次配对过程。

2024-08-03 15:40:47 250

原创 030_java.util.concurrent.LinkedBlockingDeque

LinkedBlockingDeque可以说是在LinkedBlockingQueue的基础上增加了头尾的操作能力,其大部分方法都是通过linkFirst、linkLast、unlinkFirst、unlinkLast这四个方法来实现的。其他都蛮好理解的,问题不大。

2024-08-02 17:34:27 321

原创 027_java.util.concurrent.DelayQueue

DelayQueue底层使用优先队列来存储数据,出栈入栈是转交给优先队列来执行的,在DelayQueue内部强制要求元素实现Delay方法,用来控制时间排序。在控制并发方面,使用重入锁并陈胜对应的Condition对象来保障线程安全问题。除此之外,存在leader字段存储当前操作中的线程,优化了线程阻塞通知逻辑。

2024-08-02 13:29:54 363

原创 026_java.util.concurrent.PriorityBlockingQueue

PriorityBlockingQueue是优先队列+阻塞的能力,其底层使用数组存储数据,在出队或者入队的时候不断维护堆结构。内部使用ReentrantLock保证线程安全,使用cas控制int来保证扩容行为。

2024-08-01 18:12:32 368

原创 025_java.util.concurrent.LinkedBlockingQueue

LinkedBlockingQueue底层使用链表来维护队列,存在head与last指针指向链头与链尾。其内部存在两个锁分别控制出队与入队操作。

2024-08-01 15:22:22 341

原创 024_java.util.concurrent.ArrayBlockingQueue

ArrayBlockingQueue是有界阻塞队列,底层使用数组进行存储,分配两个指针分别指向取与存的位置,逻辑上数组会被重复使用是个环形数组。内部使用ReetrantLock来控制并发,使用两个condition分别控制非满与非空条件。

2024-08-01 12:22:53 423

原创 023_java.util.concurrent.BlockingQueue

BlockingQueue是阻塞队列的接口定义,其下有非常多的实现BlockingQueue接口实现Queue接口,它支持两个附加操作:获取元素时等待队列变为非空,以及存储元素时等待空间变得可用。相对于同一操作他提供了四种机制:抛出异常、返回特殊值、阻塞等待、超时。

2024-08-01 12:22:22 291

原创 022_java.lang.ThreadLocal

ThreadLocal存储在线程对象中,在设计上可以让两个线程互不影响地操作变量。其底层使用map来存储,key是弱引用会在GC的时候被回收。map使用开放地址的策略解决冲突问题,当使用量是底层数组长度一半的时候引发扩容,变为原先容量的两倍。

2024-08-01 12:21:52 416

原创 021_java.util.Timer

Timer的功能由好几个类共同协作完成,一个是封装执行主体的TimeTask,使用TaskQueue利用堆结构进行存储。Timer内存在TimerThread执行具体任务,从TaskQueue中获得任务。

2024-07-31 17:47:48 526

原创 020_java.util.PriorityQueue

PriorityQueue是优先队列,其内部使用数组来存储数据,使用堆的方式维护数据。初始化默认11个元素的容量,在不断添加数据过程中会引发扩容,扩容需要判断旧容量是否小于64,如果小于则翻倍,否则只增加旧容量的一半。

2024-07-31 11:54:57 385

原创 019_java.util.ArrayDeque

ArrayDeque实现Deque接口,支持从队首或者队尾进行操作。其底层使用数组进行存储,分配头尾指针分别指向头节点与尾节点的下一个节点。当尾部节点追上首节点的场合下将会进行扩容,容量是之前的2倍。为保证高效处理数据,容量一直保持为2的幂。

2024-07-31 11:54:21 352

原创 017_java.util.TreeSet

TreeSet底层使用TreeMap进行存储,set相关方法大多都转向对map的请求。

2024-07-29 16:15:49 377

原创 018_java.util.BitSet

在set场景下,且数据量比较大的时候可以使用bit来存储数据是否存在,BitSet就是对这一行为的包装,其内层使用long数组来存储数据,并提供get,set方法支持针对比特位的赋值,除此之外也提供比特位相关的批量操作。

2024-07-29 16:07:26 585

算法图解.pdf,就是个简单的一个pdf

算法图解.pdf,就是个简单的一个pdf,这里有字数要求啊,哎呀哎呀,算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算法图解算

2024-07-16

空空如也

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

TA关注的人

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