<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[maohoo的博客]]></title><description><![CDATA[—— 勿以浮沙筑高台]]></description><link>https://blog.youkuaiyun.com/maohoo</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; maohoo]]></copyright><item><title><![CDATA[日常填坑 ——单一模块导致服务器整体性能下降问题排查]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/88353958</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/88353958</guid><author>maohoo</author><pubDate>Fri, 08 Mar 2019 16:32:48 +0800</pubDate><description><![CDATA[旁边的小伙伴昨天加班到今天的凌晨三点，睡在了公司，早晨我到工位时，和我说改了一晚上的上传接收逻辑（也是前一位离开的小伙伴交接的，属于顺位坑主），终于线上问题是修复了，但是只要一上传，整个项目前台页面就会响应不过来，一片白，拜托我帮他找一找问题，修复下，他已经连续通宵加班两天了，说完就骑着小电驴拖着疲惫的身躯回家了。
上传答题卡模块对于一个教育行业的公司来讲，还是一个重要核心模块，之前我还确实没有看...]]></description><category></category></item><item><title><![CDATA[日常填坑 ——linux服务器，mongodb吃内存，导致服务器缓慢]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/87938732</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/87938732</guid><author>maohoo</author><pubDate>Tue, 26 Feb 2019 17:05:46 +0800</pubDate><description><![CDATA[通过free -h 命令，发现服务器可用内存不足，并发现大量的内存被占用到buff/cache中。

一类，直接可以通过命令进行释放
sync;  echo 3 &amp;gt; /proc/sys/vm/drop_caches

可以看到，cached的19G内存已经释放。
这种情况还算比较乐观的情况，一般也不用过度分析buff/cached占比这么高的原因，比较中轨中轨的解决方案是，写一个定时脚本进行...]]></description><category></category></item><item><title><![CDATA[老生常谈，HashMap的死循环【基于JDK1.7】]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81531925</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81531925</guid><author>maohoo</author><pubDate>Thu, 09 Aug 2018 10:47:08 +0800</pubDate><description><![CDATA[转自占小狼博客



问题

如果是在单线程下使用HashMap，自然是没有问题的，如果后期由于代码优化，这段逻辑引入了多线程并发执行，在一个未知的时间点，会发现CPU占用100%，居高不下，通过查看堆栈，你会惊讶的发现，线程都Hang在hashMap的get()方法上，服务重启之后，问题消失，过段时间可能又复现了。

这是为什么？

原因分析

在了解来龙去脉之前，我们先看看HashMap的数据...]]></description><category></category></item><item><title><![CDATA[HashMap源码和JDK1.8以后的一些变化]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81506657</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81506657</guid><author>maohoo</author><pubDate>Wed, 08 Aug 2018 16:11:46 +0800</pubDate><description><![CDATA[内部实现

JDK1.8以后 HashMap的数据结构发生了一些改变,从单纯的数组加链表结构变成数组+链表+红黑树.如图  


其中的Node是HashMap的静态内部类，实现了Map.Entry接口，本质就是一个KV映射，上图中的小圆圈就是一个Node

static class Node&amp;amp;lt;K,V&amp;amp;gt; implements Map.Entry&amp;amp;lt;K,V&amp;amp;gt; {
    fin...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第五章 Java中的锁 5.6.2 Condition的实现分析]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81503242</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81503242</guid><author>maohoo</author><pubDate>Wed, 08 Aug 2018 11:23:28 +0800</pubDate><description><![CDATA[5.6.2 Condition的实现分析

ConditionObject是同步器AbstractQueuedSynchronizer的内部类，因为Condition的操作需要获取相关联的锁，所以作为同步器的内部类也较为合理。 
关于Condition的实现，主要包括：等待队列、等待和通知。


等待队列 
等待队列是一个FIFO的队列，在队列中的每个节点都包含了一个线程引用，该线程就是在Cond...]]></description><category></category></item><item><title><![CDATA[《算法和数据结构》之哈希表（hash table）]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81482114</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81482114</guid><author>maohoo</author><pubDate>Tue, 07 Aug 2018 15:47:48 +0800</pubDate><description><![CDATA[转自：www.cnblogs.com/vamei/archive/2013/03/24/2970339.html

概念

哈希表(hash table)是从一个集合A到另一个集合B的映射(mapping)。映射是一种对应关系，而且集合A的某个元素只能对应集合B中的一个元素。但反过来，集合B中的一个元素可能对应多个集合A中的元素。如果B中的元素只能对应A中的一个元素，这样的映射被称为一一映射。

...]]></description><category></category></item><item><title><![CDATA[《算法和数据结构》之队列]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81480527</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81480527</guid><author>maohoo</author><pubDate>Tue, 07 Aug 2018 14:45:02 +0800</pubDate><description><![CDATA[基本概念

队列（Queue）是一种先进先出（FIFO）的结构，类似于生活中的“独木桥”、“排队”等





对于Queue，核心api如下：




  方法
  描述



  void enQueue(T s)
  向队列中添加一个新的元素


  T deQueue()
  移除队列中最早添加的元素


  boolean isEmpty()
  队列是否为空


  int size(...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第五章 Java中的锁 5.5 LockSupport工具 5.6 Condition接口]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81475361</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81475361</guid><author>maohoo</author><pubDate>Tue, 07 Aug 2018 11:09:08 +0800</pubDate><description><![CDATA[5.5 LockSupport工具

作用：阻塞或者唤醒一个线程。

package java.util.concurrent.locks;






  方法名称
  描述



  void park()
  阻塞当前线程，调用unpark()或者被中断，才能从park()中返回


  void parkNanos(long nanos)
  阻塞当前线程，最长不超过nanos纳秒


 ...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第五章 Java中的锁 5.3 重入锁 5.4 读写锁]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81449610</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81449610</guid><author>maohoo</author><pubDate>Mon, 06 Aug 2018 13:59:55 +0800</pubDate><description><![CDATA[5.3 重入锁

重入锁（ReentrantLock）就是支持重进入的锁，它表示该锁能够支持一个线程对资源的重复加锁。

5.3.1 实现重进入


线程再次获取锁：锁需要去识别获取锁的线程是否为当前占据锁的线程，如果是，则再次成功获取。
锁的最终释放：线程重复N次获取锁，随后需要第N次释放锁后，才算释放，这期间需要维护一个计数器。


5.3.2 公平与非公平获取锁的区别

公平锁保证了锁的获取...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第五章 Java中的锁 5.2 队列同步器 5.2.2]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81381422</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81381422</guid><author>maohoo</author><pubDate>Fri, 03 Aug 2018 13:09:45 +0800</pubDate><description><![CDATA[5.2.2 队列同步器的实现分析

1： 同步队列（一个FIFO的双向队列）

 
（1）设置头节点：是通过获取同步状态成功的线程来完成的，所以不需要使用CAS来保证线程安全。 
（2）设置尾节点：加入队列需要保证现场安全，所以同步器提供了一个基于CAS的设置尾节点的方法：compareAndSetTail()

2: 独占式同步状态获取与释放

在获取同步状态时，同步器维护了一个同步队列，获取状...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第五章 Java中的锁 5.2 队列同步器 5.2.1]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81357920</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81357920</guid><author>maohoo</author><pubDate>Thu, 02 Aug 2018 15:18:22 +0800</pubDate><description><![CDATA[5.2 队列同步器

同步器（AbstractQueuedSynchronizer）是实现锁或者说任意同步组件的关键，在锁的实现中聚合同步器，利用同步器实现锁的语义。 
同步器和锁的关系：锁是面向使用者的，它定义了使用者与锁交互的接口（比如可以允许两个线程并行访问），隐藏了实现细节；同步器面向的是锁的实现者，它简化了锁的实现方式，屏蔽了同步状态管理、线程的排队、等待与唤醒等底层操作。

5.2.1...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第五章 Java中的锁 5.1 Lock接口]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81357539</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81357539</guid><author>maohoo</author><pubDate>Thu, 02 Aug 2018 14:10:39 +0800</pubDate><description><![CDATA[5.1 Lock接口

1：Lock接口出现之前，Java主要靠synchronized关键字实现锁功能。它提供了显式地获取和释放锁的便捷性，但是也缺少了synchronized的隐式获取和释放锁的便捷性，程序员可以在不同场景进行选择。 
Lock的使用也很简单，示例代码如下：

Lock lock = new ReentrantLock();
lock.lock();
try {
}finall...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第四章 Java并发编程基础 4.3 线程间的通信]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81324148</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81324148</guid><author>maohoo</author><pubDate>Wed, 01 Aug 2018 10:33:36 +0800</pubDate><description><![CDATA[4.3 线程间的通信



4.3.1 volatile和synchronized关键字

关键字volatile可以用来修饰字段（成员变量），就是告知程序任何对该变量的访问均需要从共享内存中获取，而对它的改变必须同步刷新到共享内存，它能保证所有线程对变量访问的可见性。 
关键字synchronized可以修饰方法或者以同步块的形式来进行使用，它主要确保多个线程在同一个时刻，只能有一个线程处于方法...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第四章 Java并发编程基础 4.2 启动和终止线程]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81296253</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81296253</guid><author>maohoo</author><pubDate>Tue, 31 Jul 2018 11:27:38 +0800</pubDate><description><![CDATA[4.2 启动和终止线程

4.2.1 构造线程

JDK1.8中java.lang.Thread类中的init方法源码：

private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize, AccessControlContext acc) {
    if (name ...]]></description><category></category></item><item><title><![CDATA[《算法和数据结构》之栈]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81287422</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81287422</guid><author>maohoo</author><pubDate>Mon, 30 Jul 2018 17:27:48 +0800</pubDate><description><![CDATA[1：基本概念

栈类似于生活中的死胡同，遵循后入先出的原则，即LIFO（Last In First Out）。

/** 
 * The Stack class represents a last-in-first-out 
 * (LIFO) stack of objects. It extends class Vector with five 
 * operations that allow...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第三章 Java内存模型 3.7 happens-before]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81280693</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81280693</guid><author>maohoo</author><pubDate>Mon, 30 Jul 2018 10:51:48 +0800</pubDate><description><![CDATA[3.7 happens-before

3.7.1 JMM的设计

设计意图


程序员对内存模型的使用
编译器和处理器对内存模型的实现


由于这两个因素相互矛盾，JSR-133专家组在设计JMM时的核心目标就是找到一个好的平衡点：一方面，要为程序员提供足够强的内存可见性保证；另一方面，对编译器和处理器的限制要尽可能地放松。



3.7.2 happens-before的定义

《JSR-13...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第三章 Java内存模型 3.6 final域的内存语义]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81214970</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81214970</guid><author>maohoo</author><pubDate>Thu, 26 Jul 2018 11:19:31 +0800</pubDate><description><![CDATA[3.6 final域的内存语义

3.6.1 final域的重排序规则


在构造函数内对一个final域的写入，与随后把这个被构造对象的引用赋值给一个引用变量，这两个操作之间不能重排序。
初次读一个包含final域的对象的引用，与随后初次读这个final域，这两个操作之间不能重排序。


示例代码如下：

public clas FinalExample{
    int i ;        ...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第三章 Java内存模型 3.5 锁的内存语义]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81213921</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81213921</guid><author>maohoo</author><pubDate>Thu, 26 Jul 2018 09:56:33 +0800</pubDate><description><![CDATA[3.5 锁的内存语义

3.5.1 锁的释放–获取建立的happens-before关系

锁除了让临界区互斥执行外，还可以让释放锁的线程向获取同一个锁的线程发送消息。



3.5.2 锁的释放后和获取的内存语义


当线程释放锁时，JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。
当线程获取锁时，JMM会把该线程对应的本地内存置为无效。 
总结：锁释放与volatile写有相同的语义...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第三章 Java内存模型 3.4 volatile的内存语义]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81204513</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81204513</guid><author>maohoo</author><pubDate>Wed, 25 Jul 2018 16:33:11 +0800</pubDate><description><![CDATA[3.4 volatile的内存语义

3.4.1 volatile的特性

理解volatile特性的一个好方法是对volatile变量的单个读、写，看成是使用同一个锁对这些单个读、写操作做了同步。

class VolatileFeaturesExample{
    volatile long v1 = 0L;   //使用volatile声明64位的long型变量

    public v...]]></description><category></category></item><item><title><![CDATA[读书笔记《JAVA并发编程的艺术》 第三章 Java内存模型 3.3 顺序一致性]]></title><link>https://blog.youkuaiyun.com/maohoo/article/details/81199211</link><guid>https://blog.youkuaiyun.com/maohoo/article/details/81199211</guid><author>maohoo</author><pubDate>Wed, 25 Jul 2018 13:34:00 +0800</pubDate><description><![CDATA[3.3 顺序一致性

3.3.1 数据竞争与顺序一致性

JMM对正确同步的多线程程序的内存一致性做了如下的保证： 
如果程序是正确同步的，程序的执行将具有顺序一致性（Sequentially Consistent）—— 即程序的执行结果与该程序在顺序一致性内存模型中的执行结果相同。



3.3.2 顺序一致性内存模型


一个线程中的所有操作必须按照程序的顺序来执行
（不管程序是否同步）所有线...]]></description><category></category></item></channel></rss>