<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[星坠竹空]]></title><description><![CDATA[]]></description><link>https://blog.csdn.net/shidebin</link><language>zh-cn</language><generator>https://blog.csdn.net/</generator><copyright><![CDATA[Copyright &copy; shidebin]]></copyright><item><title><![CDATA[reentrantLock]]></title><link>https://blog.csdn.net/shidebin/article/details/126819695</link><guid>https://blog.csdn.net/shidebin/article/details/126819695</guid><author>shidebin</author><pubDate>Wed, 14 Sep 2022 13:45:07 +0800</pubDate><description><![CDATA[重入的概念是什么，实现原理是什么？公平锁和非公平锁区别是什么，体现在哪些地方？没有竞争到锁的线程怎么实现等待，释放锁时又是怎么被唤醒的？发现没有是不是跟synchronized代码结构差不多，只是多了一个lock和unlock的过程。我们先画个图来对比一下synchronized和lock的数据结构：这就是学技术特别有趣的地方，你看多了感觉很多高大上的技术底层设计实际都差不多。ReentrantLock默认是非公平锁。]]></description><category></category></item><item><title><![CDATA[CountDownLatch、CyclicBarrier、semaphore]]></title><link>https://blog.csdn.net/shidebin/article/details/126820067</link><guid>https://blog.csdn.net/shidebin/article/details/126820067</guid><author>shidebin</author><pubDate>Tue, 13 Sep 2022 14:53:59 +0800</pubDate><description><![CDATA[CountDownLatch中调用await方法线程需要等待所有调用countDown方法的线程执行，这就很适合一个业务需要一些准备条件，等准备条件准备好之后再继续执行，如果一些复杂的聚合查询，还有一些类似于广播消息的功能。]]></description><category></category></item><item><title><![CDATA[零拷贝、MMAP、堆外内存]]></title><link>https://blog.csdn.net/shidebin/article/details/126833583</link><guid>https://blog.csdn.net/shidebin/article/details/126833583</guid><author>shidebin</author><pubDate>Tue, 13 Sep 2022 14:51:52 +0800</pubDate><description><![CDATA[原理：是一种内存映射文件的方法, 可以将一个文件或者其他对象映射到进程的虚拟地址空间，实现文件磁盘地址和进程虚拟地址空间中某一段地址的一一对应，这样应用程序就可以通过访问进程虚拟内存地址直接访问文件，进而达到操作文件的目的，这样就不用拷贝数据到用户态后再操作了。第三次数据拷贝：用户进程调用send()方法期望将数据发送到网络中，此时用户态会再次切换到内核态，请求的数据从用户态缓冲区被拷贝到Socket缓冲区。第二次数据拷贝：请求的数据从内核态缓冲区拷贝到用户态缓冲区，然后返回给用户进程。]]></description><category></category></item><item><title><![CDATA[ThreadLocal]]></title><link>https://blog.csdn.net/shidebin/article/details/126820316</link><guid>https://blog.csdn.net/shidebin/article/details/126820316</guid><author>shidebin</author><pubDate>Tue, 13 Sep 2022 10:35:15 +0800</pubDate><description><![CDATA[ThreadLocal实际上是通过Thread的成员变量threadLocals来发挥作用，ThreadLocal对象作为key，设置的值作为value放入threadLocals中，所以你如果使用了ThreadLocal那么当前线程就会使用threadLocals变量持有你设置值的threadlocal对象和这个threadLocal设置的值当你用threadLocal对象get方法获取值时就会通过threadLocals变量的map获取这个threadLocal设置的值。]]></description><category></category></item><item><title><![CDATA[scheduledThreadPool]]></title><link>https://blog.csdn.net/shidebin/article/details/126819011</link><guid>https://blog.csdn.net/shidebin/article/details/126819011</guid><author>shidebin</author><pubDate>Mon, 12 Sep 2022 16:29:41 +0800</pubDate><description><![CDATA[怎样做到每个任务延迟指定时间执行？内部使用了什么数据结构保存延迟任务？延迟任务放入scheduledThreadPool时机并不固定，怎么保证按延迟时间顺序执行？]]></description><category></category></item><item><title><![CDATA[CachedThreadPool]]></title><link>https://blog.csdn.net/shidebin/article/details/126818585</link><guid>https://blog.csdn.net/shidebin/article/details/126818585</guid><author>shidebin</author><pubDate>Mon, 12 Sep 2022 16:08:41 +0800</pubDate><description><![CDATA[corePoolSize是0，maximumPoolSize是Integer.MAX_VALUE，根据我们之前对源码的分析，CachedThreadPool不会有核心线程，核心线程数的addworker方法不会执行，直接尝试加入queue中。keepAliveTime是60s，也就是60s从队列中没有拿到任务，worker就会自动销毁，销毁过程在fixed的分析中已经看过了。]]></description><category></category></item><item><title><![CDATA[FixedThreadPool]]></title><link>https://blog.csdn.net/shidebin/article/details/126818287</link><guid>https://blog.csdn.net/shidebin/article/details/126818287</guid><author>shidebin</author><pubDate>Mon, 12 Sep 2022 15:50:44 +0800</pubDate><description><![CDATA[newFixedThreadPool实际上返回的是ThreadPoolExecutor，ThreadPoolExecutor实际就是线程池实现类，使用了典型的模板方法设计模式，通过ThreadPoolExecutor构造器的说明我们稍微解释一下各参数的意思：corePoolSize 核心线程数，线程池一直存在的线程（即使这些线程是空闲的），除非你设置allowCoreThreadTimeOut。]]></description><category></category></item><item><title><![CDATA[ArrayBlockingQueue]]></title><link>https://blog.csdn.net/shidebin/article/details/126817942</link><guid>https://blog.csdn.net/shidebin/article/details/126817942</guid><author>shidebin</author><pubDate>Mon, 12 Sep 2022 15:32:08 +0800</pubDate><description><![CDATA[记得LinkedBlockingQueue使用的AtomiInteger，而这里直接使用了int，这是因为LinkedBlockingQueue使用的两把锁，put和take互不干扰，所以count有多线程操作，而ArrayBlockingQueue使用的是一把锁，put和take互斥。说明元素此时已经放过数组一轮的位置了，而且通过之前的判断，现在元素的数量是没有达到数组长度的，所以数组前面的元素肯定有被take的，所以此时应该重新开始放元素。同一个作者写的，为什么会写出两个逻辑，不是很理解。]]></description><category></category></item><item><title><![CDATA[ConcurrentHashMap解析]]></title><link>https://blog.csdn.net/shidebin/article/details/126817912</link><guid>https://blog.csdn.net/shidebin/article/details/126817912</guid><author>shidebin</author><pubDate>Mon, 12 Sep 2022 15:30:21 +0800</pubDate><description><![CDATA[在初始化数组时使用cas保证只有一个线程能成功并去做初始化工作，其他线程则继续for循环在没有hash冲突时tab[i]使用cas进行赋值，保证同时只有一个线程赋值成功，其他线程则在下次for循环时进入hash冲突的代码段当有hash冲突时使用synchronized锁住tab[i]位置的元素，而且进行了双检查，保证上锁后元素没有变化，然后在锁里进行链表或红黑树的维护，保证了hash冲突时元素的插入也是线程安全的。]]></description><category></category></item><item><title><![CDATA[ConcurrentLinkedQueue解析]]></title><link>https://blog.csdn.net/shidebin/article/details/126817471</link><guid>https://blog.csdn.net/shidebin/article/details/126817471</guid><author>shidebin</author><pubDate>Mon, 12 Sep 2022 15:04:53 +0800</pubDate><description><![CDATA[add过程实际就是不停就是在单链表不断挂新元素的过程，挂next元素时使用了cas来保证线程的安全性，而且不是每次add都会移动tail指针，而是tail已经不是现在的最后一个node时才会移动tail指针。]]></description><category></category></item><item><title><![CDATA[CopyOnWriteArrayList解析]]></title><link>https://blog.csdn.net/shidebin/article/details/126815601</link><guid>https://blog.csdn.net/shidebin/article/details/126815601</guid><author>shidebin</author><pubDate>Mon, 12 Sep 2022 12:07:34 +0800</pubDate><description><![CDATA[CopyOnWriteArrayList是ArrayList多线程安全的一种实现，底层都是用数组来实现，但CopyOnWriteArrayList在add，remove，set等修改操作使用lock来保证修改的线程安全。但是读操作和集合的遍历并没有使用锁，可能会存在读写不一致的情况。]]></description><category></category></item><item><title><![CDATA[LinkedBlockingQueue源码分析]]></title><link>https://blog.csdn.net/shidebin/article/details/126815258</link><guid>https://blog.csdn.net/shidebin/article/details/126815258</guid><author>shidebin</author><pubDate>Mon, 12 Sep 2022 11:38:47 +0800</pubDate><description><![CDATA[在put元素时，首先拿到的putLock重入锁，而且记录元素个数的count也是AtomicInteger，保证了count累加的线程安全性LinkedBlockingQueue的node节点、head、tail，next等都没有使用volatile修饰，而且挂新节点也没有ConcurrentLinkedQueue那么复杂的自旋和判断，所以这就是锁带来的一个好处（或者说是锁粒度带来的好处，粒度越小可能存在的线程安全问题越多），代码复杂度会大大降低，各种多线程下写失败的情况就不会出现，]]></description><category></category></item><item><title><![CDATA[TreeMap和LinkedHashMap]]></title><link>https://blog.csdn.net/shidebin/article/details/126814905</link><guid>https://blog.csdn.net/shidebin/article/details/126814905</guid><author>shidebin</author><pubDate>Mon, 12 Sep 2022 11:18:34 +0800</pubDate><description><![CDATA[底层是基于红黑树实现，是个有序集合，按照key的compareTo方法或在构造时传入的Comparator比较器进行排序。这里需要注意如果在构造 时没有传入Comparator，那么key必须实现Comparable接口，不然会报错TreeMap是通过Comparator比较器来构建红黑树从而保证key的有序性，而LinkedHashMap是通过双向链表来保证元素插入的有序性，两者有序性的含义不是一样的。]]></description><category></category></item><item><title><![CDATA[HashMap的put源码解析]]></title><link>https://blog.csdn.net/shidebin/article/details/126814528</link><guid>https://blog.csdn.net/shidebin/article/details/126814528</guid><author>shidebin</author><pubDate>Mon, 12 Sep 2022 10:57:14 +0800</pubDate><description><![CDATA[hashMap的put方法解析]]></description><category></category></item><item><title><![CDATA[HashMap源码面试题]]></title><link>https://blog.csdn.net/shidebin/article/details/123968278</link><guid>https://blog.csdn.net/shidebin/article/details/123968278</guid><author>shidebin</author><pubDate>Tue, 05 Apr 2022 13:42:50 +0800</pubDate><description><![CDATA[总体特点：

java1.8之前使用的是数组+单向链表的数据结构，java1.8及之后使用的是数组+单向链表+红黑树的数据结构，在hash冲突形成的单向链表元素个数达到8个时会转成红黑树。
使用无参构造器初始化的node数组容量是16（在resize()方法中初始化），加载因子是0.75（也就是说当node数组中元素超过0.75容量时会进行扩容），扩容时新容量是旧容量的2倍。
扩容时java1.8之前使用的头插法，头插法可能会导致元素的丢失、hash环等问题，java1.8及之后使用的是尾插法，能够避免之前]]></description><category></category></item><item><title><![CDATA[java源码之LinkedList]]></title><link>https://blog.csdn.net/shidebin/article/details/123956897</link><guid>https://blog.csdn.net/shidebin/article/details/123956897</guid><author>shidebin</author><pubDate>Mon, 04 Apr 2022 17:22:59 +0800</pubDate><description><![CDATA[LinkedList优点：

基于双向链表实现，增删改的效率很高
可以当队列来用
LinkedList缺点：
链表的遍历时间复杂度是O（n），所以随机读是非常慢的
LinkedList使用场景：
LinkedList在生产中使用较ArrayList少很多，因为一般程序都是读多写少，LinkedList却更适合写多读少的情况。
LinkedList主要方法解析：
add(E e):在双向链表尾部插入一个元素
生成指针l指向双向链表中的最后一个元素last
生成一个新的node节点，pre是last,next是]]></description><category></category></item><item><title><![CDATA[ArrayList源码]]></title><link>https://blog.csdn.net/shidebin/article/details/123955051</link><guid>https://blog.csdn.net/shidebin/article/details/123955051</guid><author>shidebin</author><pubDate>Mon, 04 Apr 2022 15:57:08 +0800</pubDate><description><![CDATA[ArrayList优点：

随机读性能很高，因为底层是基于数组实现，可以通过get(i)寻址快速读取
获取元素个数性能很高
arrayLis天生按元素插入顺序排序
ArrayList缺点：
在扩容时需要从旧数组把元素拷贝到新数组，性能很差
在随机插入时会导致插入点之后的元素在数组中移动，性能也很差
ArrayList使用场景及使用注意事项：
在new ArrayList时最好根据业务场景进行容量的初始化，避免在之后的Add操作时触发数组的扩容，进而提高使用性能
如果有频繁的add（i,e）的操作则不建议使用]]></description><category></category></item><item><title><![CDATA[微服务架构的演进]]></title><link>https://blog.csdn.net/shidebin/article/details/109513816</link><guid>https://blog.csdn.net/shidebin/article/details/109513816</guid><author>shidebin</author><pubDate>Thu, 05 Nov 2020 15:51:56 +0800</pubDate><description><![CDATA[1.典型的微服务架构应该至少包括下图组件：

1.注册中心：作用主要是服务的注册发现和服务下线，在没有注册中心之前，两个服务的相互调用一般是通过http请求，然后把需要调用的服务名写到配置文件里，在微服务里这样做不但不够优雅，而且每个微服务都是个集群，每上一个集群服务都得该配置文件，非常繁琐，如果其中一台网络不通了也不好处理。而有了注册中心之后，所以服务都向注册中心注册，每个服务再把注册中心的服务缓存到本地，通过http请求或rpc调用。注册中心再通过心跳机制检查各注册服务的健康性，把不健康的服务及时同步到]]></description><category></category></item><item><title><![CDATA[为什么使用微服务]]></title><link>https://blog.csdn.net/shidebin/article/details/109494361</link><guid>https://blog.csdn.net/shidebin/article/details/109494361</guid><author>shidebin</author><pubDate>Wed, 04 Nov 2020 17:07:58 +0800</pubDate><description><![CDATA[1.单机服务
单机特点：在一台linux机器上部署一个tomcat服务，然后由浏览器发起http请求，tomcat将请求转发到项目由springmvc处理，经过controller-&gt;service-&gt;mapper-&gt;mysql.返回数据。
优点：维护简单，就一台服务器。
缺点：可处理的请求量有限
单机服务在公司刚成立时还是可以用的，当公司用户量慢慢增多，发现mysql服务器cpu，内存都还撑得住，但web服务器不行了，cpu和内存使用率陡增，甚至在高峰期出现宕机的情况。此时我们想到的是增]]></description><category></category></item><item><title><![CDATA[使用jstack找cpu消耗大的线程]]></title><link>https://blog.csdn.net/shidebin/article/details/109364387</link><guid>https://blog.csdn.net/shidebin/article/details/109364387</guid><author>shidebin</author><pubDate>Thu, 29 Oct 2020 17:08:38 +0800</pubDate><description><![CDATA[1.ps -ef | grep java 找到java进程id

进程id：5036
2.top -Hp 5036找到进程id 5036中占cpu最高的线程:5074

3.printf ‘%x’ 5074 把5074转成二进制:13d2

4.jstack 5036 | grep 13d2 找到线程堆栈


]]></description><category></category></item></channel></rss>