java
爱吃羊的大灰狼
这个作者很懒,什么都没留下…
展开
-
深入理解CountDownLatch之手动实现
最近有人私信博主关于CountDownLatch的源码一些细节,这对于初学者来讲学习CountDownLatch的源码还是比较困难的。为此在看源码时,应该先搞懂该类的用途,在进一步对其源码进行分析,这对看源码的你或许小有帮助,话不多说,为了帮助各位更好理解CountDownLatch是怎么回事,本文提供一个CountDownLatch的简单实现,具体代码如下:import java.util...原创 2020-01-14 22:28:51 · 388 阅读 · 0 评论 -
生产者与消费者从synchronized到ReentantLock
生产者消费者问题是经典的多线程问题,是工业化生产的模型,今天讲的就是生产者,消费者模型以及如何慢慢的改进,进而变为多消费者,多生产者。首先从简单的开始做起,假设我们只有一个生产者,一个消费者。代码实现如下plate代表着共享区,生产者和消费者可以同时操作共享区,分别生产蛋和消费蛋** * Created by lin on 2018/9/15. */public class Pla...原创 2018-09-16 20:17:46 · 220 阅读 · 0 评论 -
Spring之手写Aop(3)
到了这里也到了一个很重要的部分了,使用aop本质上是对方法使用之前,或之后添加自己的逻辑,而如何具体实现,有Aop联盟就抽象出了方法拦截器,用来执行在方法之前或之后的逻辑,而如何来调用这些拦截器,拦截器的执行顺序如何呢?这有引出了方法调用器(我自己取的, 也就是MethodInvocation)首先来看一下方法拦截器的定义 // Source code recreated f...原创 2018-08-30 12:11:33 · 486 阅读 · 0 评论 -
Spring之手写Aop(1)
aop,面向切面编程,是面向对象的一种补充,手写之前请确保有一下基础知识,分别为java注解的基本使用,java动态代码,了解spring框架,了解beanPostProcessor的作用,以及掌握java的适配器模式。为了简化开发量,这里借助spring。开发的出的框架遵守aop联盟,实现方法与spring自带的Aop实现方式略有不同,但原理相同在实现方面,另辟道路,通过注解的方式表明 ...原创 2018-08-30 12:06:19 · 738 阅读 · 0 评论 -
Spring之手写 Aop(4)
上几篇提到分别提到了方法拦截器,和advice等通知,在上面的过程中,框架使用者通过实现MethodBeforeAdvice等接口来来表示在操作某个方法之前或之后应该做什么,而我们的程序中通过方法拦截器来表示在方法之前或之后应该做什么,两者不一样?该如何解决呢? 不错,这时候就需要用到java的设计模式——适配器模式了首先定义适配器接口,明确适配器的功能package com.aut...原创 2018-08-30 12:02:47 · 243 阅读 · 0 评论 -
一篇文章带你详解定时器 Timer 的运行机制
本篇博文基于jdk1.8对Timer定时器进行深入分析,带你详解Timer定时器的原理package java.util;import java.util.Date;import java.util.concurrent.atomic.AtomicInteger;public class Timer { private final TaskQueue queue = ne...原创 2018-08-31 09:34:04 · 1531 阅读 · 0 评论 -
深入分析ScheduledThreadPoolExecutor的源码
上篇文章我们讲解了Timer的实现机制,但是Timer定时器是单线程的,如果该线程终止的话,那么定时任务将无法执行,为此jdk1.5后推出了ScheduledThreadPoolExecutor,用于执行定时任务,为此我们在这里就分析一下ScheduledThreadPoolExecutor的具体实现么,因为ScheduledThreadPoolExecutor是基于ThreadPoolExecu...原创 2018-09-01 17:54:00 · 249 阅读 · 0 评论 -
Spring之手写Aop(6)
本章将主要讲解Aopsupprot 和JDkDynamicProxy,写到这里这个简易的aop框架也就要结束了,真个项目我也上传地址为https://github.com/skybluehhx/MyAop.git.首先看一下AopSupport的实现package com.support;import com.MethodConfig;import com.ProxyConfig;...原创 2018-08-30 12:12:08 · 299 阅读 · 0 评论 -
Spring之手写Aop(5)
前面我们已经对MethodInterceptor,advice等类给出了介绍,并给出了具体的实现,接下来的问题时框架如何知道用户启动aop换句话说 ,框架如何知道用户能够对方法启动了代理,答案就是注解,这里借助一个beanPostProcessor+java注解(EnableAop,interceptorAdvice前面已经做了介绍,这里不再重复)的方式来实现,利用beanPostProcesso...原创 2018-08-30 11:51:13 · 304 阅读 · 0 评论 -
阅读AQS及其衍生类Semaphore、CountDownLatch、ReentantLock等源码的感悟
曾今阅读过AQS,Semaphore,CountDownLatch,ReentantLock,等并发包的源码,其中后面三个类都是基于AQS实现的,AQS是同步框架的基石,不同的衍生类可以实现tryAcquireShared(主要共享锁实现)tryReleaseShared(主要共享锁实现)tryAcquire(独占锁实现),tryRelease(独占锁实现),以此来实现不同的并发框架,来满足不同的...原创 2018-09-10 23:08:54 · 233 阅读 · 0 评论 -
求一个数中1的个数
碰到遇到一个有趣的题,求一个数二进制的表示中1的个数,该题有两种解法,一种是使用短除法将该数直接转化为二进制数,另一种比较巧妙的算法是使用与运算,原理如下图所示 依照此种思入有如下算法int NumberOf1_Solution3(int i){ int count = 0; while (i>0) { ++ co...原创 2018-09-06 22:37:28 · 655 阅读 · 0 评论 -
时间复杂度为O(1)的LRU算法
LRU,算法在操作缓存中常常被用到,由于其访问频繁,因此缩小LRU时间复杂度是非常必要的,好的LRU算法的实现能够很好的提高系统的稳定性数据结构中map的访问速度非常快,时间复杂度为O(1),因此在缓存结构中,可以借助map结构,同时由于缓存需要容量满时需要删除操作,并且对于最近被访问的需要重新置于头部,在数据结构中链表能够很好的完成该操作,故缓存结构借助map加链表结构来降低时间复杂度,...原创 2018-09-19 01:38:59 · 3967 阅读 · 0 评论 -
利用注解优雅解决Springboot+mybatis多数据配置问题
最近在开发项目中(ORM层用的是mybatis),需要连接多个数据库,这时候就涉及到多数据源使用了。为了优雅的解决此问题,我们可以使用装饰者模式并修改了mybatis的实现源码来优雅的解决此问题 由于代码量有点多,文章篇幅有限,就不在此详细的搬出,具体的代码已放到git 飞机票如下https://github.com/skybluehhx/mulitDataSource.git(现已更新支持注解的...原创 2019-07-04 23:03:44 · 264 阅读 · 0 评论 -
事务的一致性设计(2阶提交和3阶提交)
看到一篇关于事务的好文章,里面对2阶提交,3阶提交,柔性事务都讲解的比较好,因为涉及到侵权的原因只能放链接了,不能转载,感兴趣的小伙伴直接去看原文吧 ...转载 2018-10-13 20:49:58 · 197 阅读 · 0 评论 -
简易服务网关的实现
网关服务是单一访问点,并充当多项服务的代理。服务网关启用了跨所有服务的路由转发、过滤和公共处理等。在微服务实践中远不止这点功能,它可以做到统一接入、流量管控、安全防护、业务隔离,权限管理等等等功能。下面是服务网关的大概作用图。 本质来讲服务网关就是在请求来临做一定的处理(如,权限验证,请求转发),从而决定该请求如何进行(如:转发到后台服务,直接拒绝处理),这有点类似spr...原创 2018-10-06 21:28:36 · 1171 阅读 · 0 评论 -
RateLimiter 源码分析
RateLimiter为guava包下以令牌桶算法抽出来的基类。在这里要说明一下,在令牌桶算法中,理论上是要每隔一定的时间往桶里添加令牌,具体的实现方式有两种第一种:常规实现是采用定时任务,每隔一定的时间往桶里添加令牌 ,该种方式需要额外开启后台线程,消耗资源第二种:(补偿思路) 保存下一次需要添加令牌的时间nextFreeTicketMicros,每次请求时,进行补偿(核对当前时间是否...原创 2018-10-04 23:38:35 · 569 阅读 · 0 评论 -
简易时间轮的实现
在处理大量的延迟任务的时候jdk自带的延迟定时任务队列在处理延迟任务(如删除,修改)需要logn的复杂度,这并不能满足已有的需求,于是时间轮延迟算法被设计出来,其原理是模仿生活中的时钟,已每过一段时间,移动一格并执行该格中的任务队列,需要放置任务时,只需要放到当前格的前一格即可,待下次(走满一圈)再次走带该位置在执行此任务,此任务延迟的执行的时间就等于每格所代表的时间*总共的格数,关于时间轮算...原创 2018-10-02 23:22:29 · 751 阅读 · 2 评论 -
LRU(多线程)缓存的实现
前面写了个lru缓存,适用于单线程的场景。多线程实现缓存的思路有很多种,有基于ttl淘汰策略的,有基于lru淘汰实现的,而在淘汰的方式也有很多选择,如果选用Concurrenthashmap,可以很好的基于ttl淘汰策略,具体实现是另开一个守护线程,定时淘汰ConcurrenthashMap中的过期键,而在使用lru淘汰策略时则需要额外借助辅助结构双向链表,需要额外的同步操作,由于在本文之前实现了...原创 2018-09-20 14:27:28 · 2966 阅读 · 1 评论 -
线程间各种转态的切换,以及等待队列与同步队列的区别
面试的时候曾被问到过线程间状态的转换问题,自己回答的不是太好,故查阅了一些资料来巩固这一片空白,资料参考自微信公众号 java团长。首先线程总共有六种状态,分别是初始,运行,阻塞,等待,超时等待,终止转态。第一种:初始(NEW)指新建一个线程对象如Thread thread = new Thread(()->{});还没有调用其start() 方法。第二种:运行状态(RUNNAB...原创 2018-09-14 22:18:23 · 2442 阅读 · 1 评论 -
高并发请求之页面静态化
在高并发请求中(如秒杀系统)需要将请求尽量拦截在上游,减轻下游的压力,常用的在前端的方式有,限定点击次数,检测ip防止脚本式的攻击,页面静态化,后端一般使用消息队列+缓存的形式,一次来最大的拦截无用请求,最小化查询数据库次数,从而减轻服务器压力,达到高并发。今天就实战一下也页面静态化,学习之前请确保会springMVC的基本知识。 什么是页面静态化:我的理解就是对页面进行缓存,当请求来临时,我...原创 2018-09-25 16:10:35 · 464 阅读 · 0 评论 -
详解RPC实现需要动态代理
RPC通俗的讲就是在本地调用服务器端服务。而实现RPC框架用到的一项重要的技术就是动态代理技术,首先先讲一下为什么使用动态代理(不知道动态代理的 可以自行百度一下动态代理)技术我们知道 在使用动态代理时有一个这样的方法public Object invoke(Object proxy, Method method, Object[] args) 使用在客户端,使用动态代理代理客户端发送请求有两优点...原创 2018-07-15 21:27:44 · 2101 阅读 · 0 评论 -
最近最久未使用
//添加的数据类型package com.lin;import java.util.Objects;public class LRUData <T> { T val; LRUData next; public LRUData(T t){ this.val =t; } @Override public boolea...原创 2018-07-15 09:53:11 · 632 阅读 · 0 评论 -
合并两个有序的链表
题目:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 思路来源于 归并排序 合并两有序的数组:思路是 有两个指针分别指向待合并的链表的头结点,将两个指针数值较小的指针后移,直到有一个为空具体实现代码 /*public class ListNode { int val; ListNode next = null;...原创 2018-07-20 09:12:05 · 104 阅读 · 0 评论 -
java之实现自己的线程池
首先要明白线程池的作用,根本作用是维持一定的线程数去执行任务(也会是run方法) 弄明白这一点我们就可以写一个简易的线程池了 首先定义自己的线程池接口 ;package com.MyThread.Mytest;import java.util.List;public interface MyIThreadPool { //执行任务 在执行任务时请确保任务添加完毕; ...原创 2018-07-19 20:57:11 · 3572 阅读 · 2 评论 -
变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 思路:递归求解 第n中跳法为第一次跳1个台阶加跳n-1个台阶的跳法 ,第一个跳2个台阶加跳n-2个台阶的跳法 ....一直到到第一次跳n-1加跳一个台阶的跳法,再到一次跳n个台阶 故有此算法public class Solution { public int...原创 2018-07-18 21:44:58 · 108 阅读 · 0 评论 -
Method 是否能调用的判断
首先让我们看一下java中的动态代理,我也是从中受到启动的定义一个接口package com.TestProxy;public interface IFruit { void eat(String i); void shape(String i);}接着有个实现类package com.TestProxy;public class Apple impleme...原创 2018-07-23 19:46:48 · 698 阅读 · 0 评论 -
海量积分排名 简化后的具体实现
首先积分值有个最大值,积分由n变化到m 排名变化的只是在积分n到积分m的客户排名会发生变化故此 有如下实现使用RankAndNum来表示处在该积分的排名和数值使用RankAndNums数值来保存所有积分排名(注意:RankAndNums[n]中RankAndNum中的rank和Num则表示积分为n的排名和处在积分为n的用户数量)看下面积分改变时注意自己画图理解,积分由n上升到m时位于n到m...原创 2018-07-17 22:39:44 · 569 阅读 · 0 评论 -
两个线程交替打印奇偶数
在做这个代码之前,其实碰到了一些问题,不过说到底还是基础不行,总结出来就是 切不要以Integer等作为锁的对象,也就是被锁住的引用 所指向的对象一定不能变,用integer极其容易引起所指向对象的改变 如 i = i+1;等等 切记 切记 。否则会报错哦,(非法对象监视器异常)例如 : 有个Integer i对象 synchronized (i) { i =i+1; i.wait...原创 2018-07-26 13:30:27 · 561 阅读 · 0 评论 -
布隆过滤器的简易实现
布隆过滤器的原理再此就不重复说了,网上有很多种陈述的,再此就利用BitSet给出一个布隆过滤器的简易实现,看不懂的欢迎私信我 import java.util.BitSet;/** * @author zoujianglin * @date 2018/8/9 9:27 */public class SimpleBloomFilter { private stati...原创 2018-08-09 09:49:16 · 599 阅读 · 0 评论 -
一篇文章带你了解AQS的原理及流程
本文带你了解jdk1.8版本AQS源码的原理及执行流程,由于AQS源码过长,在这里就不粘贴复制了,自己去jdk看源码就行这里我只讲AQS的主要流程给详解一下(主要是doAcquireShared方法这也是最关键的算法) 为此我画了一个流程图。具体如下 上面流程基本对每个个方法都做了介绍,相信对着上面的介绍在看源码,你肯定会轻松很多,这里就不对上面所提到的方法一 一从jdk...原创 2018-08-27 13:36:49 · 1517 阅读 · 0 评论 -
java之实现自己的数据库连接池
最近仿mybatis写了一个自己的orm框架 项目已上传到github上 https://github.com/skybluehhx/MYORM.git,既然是orm框架肯定需要事务管理器和数据库连接池,下面将介绍我自己实现一个连接池 (主要借助阻塞队列)首先定义一个接口,给出线程池的基本功能package Pools;import java.sql.Connection;/**...原创 2018-08-26 18:52:00 · 2103 阅读 · 1 评论 -
深度解析CyclicBarrier源码 (全注释版)
CyclicBarrier 相对于CountDownLatch来讲其源码是简单多了,CountDownlatch的使用场景一般是一等多,CyclicBarrier的使用场景为多个线程互相等待,当然对CountDownLatch有兴趣的博友可以看一下我这篇博客对于CountDownlatch源码的分析https://blog.csdn.net/qq_32459653/article/details/...原创 2018-08-13 20:39:39 · 743 阅读 · 0 评论 -
java.concurrent包之DelayQueue源码分析
延迟队列在java并发包中 其源码来说相对较简单,下面就让我们来分析一下延迟队列的实现,以下是基于jdk1.8实现的DelayQueue的主干代码 package java.util.concurrent;import java.util.concurrent.locks.*;import java.util.*;public class DelayQueue<E e...原创 2018-08-13 17:39:25 · 159 阅读 · 0 评论 -
ReentrantLock源码浅析(公平锁,非公平锁如何实现)
ReentrantLock 有两种实现锁的方式 一种是非公平的,一种是公平的,默认的实现方式是非公平的,但不管哪种实现方式,ReentrantLock都是依靠的它的静态内部了syc来实现,底层的实现机制都是利用volatitle语义 和操作系统提供的CAS原语来实现所以在看本篇博文时请确保你有以上基础 ,下面上源码 (jdk1.8)public ReentrantLock() { ...原创 2018-08-03 11:11:35 · 499 阅读 · 0 评论 -
深度解析CountDownLatch源码(包括锁的释放细节)
首先CountDownLatch的作用在这里就不多说了,就是一个闭锁,其实现基于AQS, 想要理解它的实现原理就请有耐心的看完本篇博文,看了之后基本就掌握的七七八八了,下面我们就来分析吧 public CountDownLatch(int count) { if (count < 0) throw new IllegalArgumentException("count ...原创 2018-08-07 20:22:47 · 7355 阅读 · 7 评论 -
深入理解异步获取future 之实现自己的Futuretask
上篇博文带大家解析了future的原理,没看请走直通车https://blog.csdn.net/qq_32459653/article/details/81558342总的来说future的原理是,其他线程在获取的是否检查任务是否完成,完成了我们直接返回,没完成我们就阻塞,等到完成后再唤醒所有线程,这个是根本思想,已经这个这个思想,我们实现一个自己的futureTask,并且,我们这个fu...原创 2018-08-10 17:28:01 · 1448 阅读 · 0 评论 -
线程池future实现的基本原理以及实现自己的submit方法
昨天有幸看书的时候看了一下netty的chnnelfuture,其原理感觉应该跟java的callable实现的原理应该差不多,既然这样我们先将java的future先弄个明白,java的callable能通过future拿到返回值,虽然以前也知道有这么一回事但并没有过多的关注,这次正好看一下源码来搞明白其中的奥妙 首先看下面一段示意的代码.public static void main(S...原创 2018-08-10 11:06:12 · 3185 阅读 · 1 评论 -
从零到实现自身AOP框架
在阅读本文前首先请确保会java的动态代理技术springAOP大家都知道使用的动态·代理技术,当然这个技术是根本,其实在Spring在处理AOP的时候还使用了链式处理举个例子 例如一个类 有多个前置增强 (即全都在代理目标类方法前执行)又有多个后置增强(全都在方法目标类的后面执行) 如何确保前置增强执行完后再执行代理目标类方法 最后在执行后置增强呢,答案是使用链式处理,先理解下链式处理 ...原创 2018-07-17 16:33:28 · 230 阅读 · 0 评论