Java中,想要创建一个线程池有两种方式,分别是使用Executors的工厂方法创建和直接使用ThreadPoolExecutor去创建一个线程池。 在阿里巴巴开发手册中有讲,在有多线程开发的需求时,强制使用线程池,避免因为“过度切换”而引起的资源耗尽问题,并且创建线程池时需通过ThreadPoolExecutor的方式去创建。原文如下: 【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。 说明:使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。 【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors返回的线程池对象的弊端如下: 1)FixedThreadPool和SingleThreadPool:   允许的请 继续阅读 >>


祝一迪 18/11/26 12:05:26
前几天在使用mybatis框架自定义mapper方法的时候报了这个错,现在把这个原因记录一下。 bug原因: 该自定义mapper方法用来返回表的主键ID这一列,mapper文件内容如下: <select id="selectId" parameterType="com.service.dao.TestQuery" resultMap="java.util.List"> select <if test="distinct"> distinct </if> id from test_table </select> 原因就出在resultMap=“java.util.List"这里,因为我要返回的数据是一个List,所以就用了resultMap和"java.util.List”。 bug修改: 将resultMap改为resultType 将java.util.List改为java.lang.Long(mybatis会自动将查 继续阅读 >>


祝一迪 18/11/16 18:29:10
最近在开发的过程中有一个点让我比较感兴趣,就是使用Lambda表达式的方式来实现Comparator接口。 1. 关于Comparator和Comparable 既然提到了Comparator,那就大致来说一下Comparator和Comparable接口的区别。 Comparator是一种策略模式,即被比较的对象自身不需要做任何改变(实现任何排序接口),而是通过实例化一个Comparator策略来实现对象之间的排序。 Comparable支持对象自身进行改变(对象自身实现Comparable接口),从而具有排序功能。 举个例子来说,一组对象需要用Collection的sort方法进行排序,有两种方法,要么是对象实现Comparable接口,自身具有可排序属性;要么是实现一个Comparator比较器,在调用sort方法时传入。 下面再来说一说Lambda表达式。 2. Lambda表达式 我们都知道,Lambda表达式是Java里面的函数式编程,那么在使用Lambda表达式首先要满足这样一个条件:首 继续阅读 >>


祝一迪 18/11/06 21:33:23
在使用IDEA开发比较大的Spring web项目的时候,常常会在pom文件中导入大量依赖,所以就有可能造成Maven的依赖冲突。下面来看一下如何解决Maven的依赖冲突。 1. 先清当前的jar包的缓存: IDEA的 File选项 -> invalidate caches/restart 2. 打印Maven的依赖树: mvn dependency:tree (建议将内容重定向到一个file里,方便查看,如:mvn dependency:tree > file.txt) Maven的依赖树的样式如下,图中圈出了一个包与其下所有子包的层级关系: 3. 定位产生依赖冲突的子包: 比如新加了xxx包之后,产生了依赖冲突,那么在file.txt依次全文搜索xxx包下依赖的所有子包,看看是否由别的包也依赖此子包。 如果在别的包(比如yyy包和zzz包)下面也发现有该子包,那么说明需要在xxx包、yyy包、zzz包其中两个包下排除这个子包的依赖,只保留一个包下的该子包的依赖。 那么,具体应该保留哪个 继续阅读 >>


祝一迪 18/10/25 20:51:53
1. JVM的内存结构 JVM的内存结构主要是指Java程序在运行时的数据区的划分. 它主要由虚拟机栈, 本地方法栈, Java堆, 方法区, 程序计数器这五部分组成. 这五部分, 虚拟机栈/本地方法栈/程序计数器是线程私有的, Java堆和方法区是线程共享的. 下面我们就来逐一介绍一下这五部分. (1) 虚拟机栈 虚拟机栈是线程私有的, 所以它的生命周期与线程相同. 在Java程序的执行过程中, 每调用一个方法, 就会创建一个栈帧. 栈帧是描述Java方法执行的内存模型, 它用于存储局部变量表, 操作数栈, 动态链接, 方法出口等信息. 而每一个方法的调用到结束, 都对应着一个在虚拟机栈中从入栈到出栈的过程. 在虚拟机栈中, 最重要的就是局部变量表. 局部变量表 局部变量表存放了编译器可知的八种基本数据类型, 对象引用(引用类型), returnAddress类型(指向了一条字节码指令的地址). double和long类型的数据会占用两个局部变量空间, 其余的数据类型只占1个. 局 继续阅读 >>


祝一迪 18/02/07 00:04:03
观察者模式是JDK中使用最多的设计模式之一. 在学习观察者模式之前, 我在网上也找了很多博客, 这些博客都是的讲解都是基于 head first 设计模式 这本书的. 如果看书的话, 很简单就能学会这个设计模式, 但是将书上的内容些成博客, 其实是不太容易理解的. 所以在这篇博客中, 我将用我自己的方式以示例的方式来讲解这个设计模式. 1. 观察者模式是什么? 它解决了什么问题? (1) 观察者模式是什么? 观察者模式由两个端组成, 分别是通知者(speaker)和观察者(listener). 观察者也可以称为监听者. speaker和Listener是一对多的关系. 当speaker的状态发生改变时, 可以将这种改变通知给它所有的Listener. (2) 解决了什么问题? 假如现在speaker里面做了某些操作后, 它需要将这些操作的结果(或者某些数据)告诉它所有的listener, 最容易想到的办法就是通过方法调用来实现, 但是这样就使得这多个listener和spea 继续阅读 >>


祝一迪 18/02/05 00:30:20
本文主要是从我写Java网络编程时使用BufferedInputStream和BufferedOutputStream的时候遇到的bug, 来分析BufferedInputStream和BufferedOutputStream的工作机制和简单的源码分析. 1. bug描述 最近在写一个Java网络编程的程序, 其中涉及文件的传输问题, 选择使用BufferedInputStream和BufferedOutputStream来作为网络通信读取数据的方式. 在进行测试的时候, 大文件(几百兆甚至上G)是没有问题的, 但是偶然间测试小文件(十几B)总是失败. 大文件传输成功, 小文件传输不成功, 这说明并不是代码逻辑上的问题, 而应该是某个细节的问题. 经过一番仔细考虑, 去看了看BufferedOutputStream和BufferedInputStream的源码, 终于发现是缓冲区的问题. 小伙伴在看了这博客之后说, 只描述bug对一个陌生人来说不具有太大的参考意义. 所以在这里 继续阅读 >>


祝一迪 18/02/01 12:30:34
1. bug描述 今天写代码的时候出现了一个问题, 前端页面的一些小图标不见了, F12之后, 发现报错信息如下: Failed to decode downloaded font: http://localhost:8080/font-awesome-4.7.0/fonts/fontawesome-webfont 当然这只是其中的一条, 因为由好几个图标都不能显示, 所以有好几条这样的报错信息. 2. bug解决 我先google了一下这个错误信息, 并没有找到正确的解决方案, 但是有一个博主说是因为工程中使用了Maven, 没有在pom.xml设置过滤信息, 从而导致了bug, 具体解释点击这里. 然而这并没有解决我的问题, 因为我的pom.xml和他的格式不一样, 并且没有设置任何拦截. 但是这位博主给了我一个重要的提示, 那就是查看我的过滤器!!! 果然问题出现在过滤器中, 在过滤器中的非过滤URI字段数组中, 我只添加了css/js/img等, 而没有添加这个用于显示图标的” 继续阅读 >>


祝一迪 17/12/23 00:26:07
1. bug描述 今天在合前端和后台的代码的时候出现了让人头大的问题, 前端页面乱码, 并且css/js格式不能显示出来. 前端页面是大壮写好的HTML页面, 我合后台代码的时候直接将后缀改为了.jsp, 就出现了乱码. 2. bug原因 首先前端页面出现乱码可以分为两种情况, HTML和JSP. (1) HTML乱码解决 HTML乱码的原因是网页源代码的编码与网页中的中文编码不同导致, 这样就会导致浏览器无法对网页中的中文进行正确解析, 所以一般要在HTML页面的头部加上下面的代码来设置编码: <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> (2) JSP乱码解决 如果你是正正经经地创建一个JSP页面, 并且在头部加了上面HTML中设置编码的代码之后, 一般就不会出现什么问题. 但是我今天就是在JSP中已经加了上面的代码, 但是乱码问题还是没有得到解决. 原因是 继续阅读 >>


祝一迪 17/12/13 17:31:44
今天Java上机的时候有一道题是这样的: 本题目要求定义一个长度可变的整型数组IntArray,数组初始长度为5,当输入的数组元素个数超过数组长度时,数组就自动增加5个元素的容量,即数组长度增加5。 也就是说实现一个类似于ArrayList的自动扩容int型的数组. 既然类似于ArrayList, 那不妨来看看ArrayList是如何动态扩容的. ArrayList是集合类List基于数组的一个实现, 也就是说, ArrayList底层实质上就是一个Object[]数组. 但是数组是定长的, 而我们在使用ArrayList的时候之所以不会有这样的感受就是因为它封装了内部的数组扩容操作, 所以ArrayList如何安全的实现扩容就成了我们的关注点. 1. ArrayList底层数组容量的初始化 在ArrayList初始化的时候, 是可以通过参数initialCapacity来指定底层数组的初始大小. 其构造方法源码节选如下: // ArrayList的默认容量为10 priva 继续阅读 >>


祝一迪 17/11/29 23:02:56