Semaphore信号量之AQS共享锁-非公平模式

之前我们已经讲解过关于AQS的独占锁,这一章节主要讲解AQS的共享锁,以`Semaphore`信号量来进行讲解,相信通过看了本章节内容的同学可以对AQS的共享模式有一个了解,`Semaphore`信号量提供了用于控制资源同时被访问的个数,也就是它会维护一个许可证,访问资源之前需要申请许可证,申请许可证成功后才可以进行访问,如果申请访问资源获取的了许可证,则可以进行资源访问,同时颁发许可证中心的许可证会进行增加,等到访问资源的线程释放资源后,许可证使用情况会进行减少。

Java线程池原理浅析

为了避免频繁重复的创建和销毁线程,我们可以让这些线程进行复用,在线程池中,总会有活跃的线程在占用,但是线程池中也会存在没有占用的线程,这些线程处于空闲状态,当有任务的时候会从池子里面拿去一个线程来进行使用,当完成工作后,并没有销毁线程,而是将将线程放回到池子中去。

图解AQS原理之ReentrantLock详解-公平锁

前面已经讲解了关于AQS的非公平锁模式,关于`NonfairSync`非公平锁,内部其实告诉我们谁先争抢到锁谁就先获得资源,下面就来分析一下公平锁`FairSync`内部是如何实现公平的?如果没有看过非公平锁的先去了解下非公平锁,因为这篇文章前面不会讲太多内部结构,直接会对源码进行分析,所以建议先读取前篇文章。

图解AQS原理之ReentrantLock详解-非公平锁

并发编程中,`ReentrantLock`的使用是比较多的,包括之前讲的`LinkedBlockingQueue`和`ArrayBlockQueue`的内部都是使用的`ReentrantLock`,谈到它又不能的不说AQS,AQS的全称是`AbstractQueuedSynchronizer`,这个类也是在`java.util.concurrent.locks`下面,提供了一个FIFO的队列,可以用于构建锁的基础框架,内部通过原子变量`state`来表示锁的状态,当`state`大于0的时候表示锁被占用,如果state等于0时表示没有占用锁,`ReentrantLock`是一个重入锁,表现在`state`上,如果持有锁的线程重复获取锁时,它会将`state`状态进行递增,也就是获得一个信号量,当释放锁时,同时也是释放了信号量,信号量跟随减少,如果上一个线程还没有完成任务,则会进行入队等待操作。

SynchronousQueue原理详解-非公平模式

面已经讲解了公平模式的内容,今天来讲解下关于非公平模式下的SynchronousQueue是如何进行工作的,在源码分析的时候,先来简单看一下非公平模式的简单原理,它采用的栈这种FILO先进后出的方式进行非公平处理,它内部有三种状态,分别是REQUEST,DATA,FULFILLING,其中REQUEST代表的数据请求的操作也就是take操作,而DATA表示的是数据也就是Put操作将数据存放到栈中,用于消费者进行获取操作,而FULFILLING代表的是可以进行互补操作的状态,其实和前面讲的公平模式也很类似。

系统栈的工作原理

本篇文章着重写的是系统中栈的工作原理,以及函数调用过程中栈帧的产生与释放的过程,有可能名字过大,如果不合适我可以换一个名字,希望大家能够指正,小丁虚心求教!如果有哪里写的不清楚的或者错误的地方请及时更正,小丁再次谢过了。文章里面有错别字,也可能会有好友说寄存器的32、16位的区别其实我感觉这里主要讲的还是些原理性的东西,后续会将文章图片错别字进行调整.(图片里面的posh改为push)

LinkedBlockingQueue原理解析

通过上面的UML可以看到,他也是BlockingQueue的实现,也就是他的核心在于Blocking(阻塞)这个上面,在讲解ArrayBlockingQueue的时候,可以清晰的得出ArrayBlockingQueue是使用了独占锁的方式,要求两个操作进行时获得当先队列的独占锁,那么take()和put()操作就不可能真正的并发。它们会彼此等待对方释放资源,在这种情况下所竞争会比较激励,从而会影响到高并发的效率,而LinkedBlockingQueue为了解决这一问题,采用`锁分离`的方式进行实现,take()函数和put()函数分别实现了从队列中取得数据和往队列天价收的功能,换句话说就会说take()方法有专门的锁进行控制,而put()方法也有专门的锁进行控制,由于take()方法是操作队尾,put()方法操作队首,又因为LinkedBlockingQueue是基于链表的方式实现,因此两个操作不受影响。