java
文章平均质量分 63
绝世好阿狸
这个作者很懒,什么都没留下…
展开
-
【Java】ThreadLocal
ThreadLocal作用线程级别变量隔离,减少多线程访问变量时加锁带来的性能损耗。缺点使用不当可能导致oom。原理弱引用是精髓。get方法 public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = m原创 2021-05-17 00:02:44 · 1001 阅读 · 0 评论 -
【Java】四种引用
Java引用类型分为4种。1.强引用正常来说,用一个引用指向new出的对象,都是强引用类型。比如String s = new String(""); 这里的s就是一个强引用。如果对象被强引用指向,那么这个对象无论如何都不会被gc回收,即便发生oom。2.软引用String s = new String("abc");SoftReference<String> r = new SoftReference<>(s);软引用的特点是,如果对象仅仅被软引用指向,gc时原创 2021-05-16 23:31:11 · 309 阅读 · 0 评论 -
【网络IO模型(三)】Reactor 模式
/** * Reactor模式简述 * * Reactor负责轮询selector,将就绪事件分发给handler处理。 * handler大致有两种: * 1.acceptor:负责建连,建连后注册io handler; * 2.io handler:负责处理io读写事件; * * 所以Reactor模式是一种事件响应式模式。提前注册handler。selectionKey的作用是将handler与channel关联(注册事件时不能指定handler) * 当select返回就绪事.原创 2021-02-27 23:22:34 · 384 阅读 · 0 评论 -
【网络IO模型(一)】BIO vs NIO
先回顾下几个概念。阻塞 vs 非阻塞:指的是调用者线程会不会被阻塞。BIO就是一种阻塞io,如果没有就绪,调用者线程会被阻塞挂起。而NIO是非阻塞的。同步 vs 异步:指的是调用方式,同步调用可以理解为调用结果需要调用者主动获取,而异步调用则是使用回调/通知机制,将结果回调给调用者,调用者无需关心。可以看到,二者是两个维度的概念,没有绑定关系。同步调用可以是阻塞的也可以是非阻塞的,比如BIO和NIO。异步调用通常是非阻塞的,比如AIO。目前现状是BIO和NIO占绝大多数的场景,AIO却用的不原创 2021-02-27 15:13:23 · 242 阅读 · 1 评论 -
【Java】异常日志只打印一行
一直以为是日志系统的功能,今天发现是jvm实现的,参数是:OmitStackTraceInFastThrow,并且只针对特定5种异常开启。详见:https://www.javajike.com/article/1768.html转载 2021-02-23 11:10:19 · 1647 阅读 · 0 评论 -
Netty HashedWheelTimer 介绍
HashedWheelTimer是netty开发包里时间轮组件,可以用于提交延迟任务。Java里的Time组件也具备相同的功能,不过Time是基于优先队列实现的,相当于需要对所有的任务基于执行时间排个序,复杂度是logn。而HashedWheelTimer是另一种思想,预先放置一定数量的任务槽,任务提交时,根据延迟时间放入对应的槽位。工作线程利用sleep模拟tick,将到达的槽位里的任务取出,依次执行。极端情况下是On,如果槽位足够大,接近于O1。使用 public static void原创 2020-11-22 19:16:53 · 1390 阅读 · 0 评论 -
【Java】Guava里Maps#transformValues方法导致异常无法catch
/** * guava开发包里的Maps#transformValues方法可能会导致异常catch不住。当然不是说guava实现有bug,是指使用者很可能不了解其实现原理,导致问题发生。 * Maps#transformValues的实现是lazy的,也就是调用该方法生成的map不是替换value之后的map,而是原始value+transfer function的map,是一个内部实现类TransformedEntriesMap。 * 也就是说我们的transfe...原创 2020-11-16 14:00:02 · 897 阅读 · 0 评论 -
【Java】 java -jar 命令 传递系统参数 与 main函数参数 顺序
package com.liyao.runner;/** * 用法: java [-options] class [args...] * (执行类) * 或 java [-options] -jar jarfile [args...] * (执行 jar 文件) * 可以看到,jvm参数和程序参数的传参位置是不同的,jvm参数常见的是一些系统变量,会通过-D参数指定,这类型参数是[-options]里的,需要放在执行的主类名或者jar包之前.原创 2020-09-03 11:23:07 · 4112 阅读 · 0 评论 -
【Java】正则表达式 Pattern Matcher
Pattern:生成一个正则表达式的模板,一般而言,不会用到Pattern的其他方法。步骤:1.首先调用其静态方法compile,生成一个正则表达式的模板;2.调用生成的Pattern实例的matcher方法,获得一个Matcher类型的实例;Matcher:是一个有状态的类型,正则匹配的过程都是在这个类里完成的。为什么是有状态的呢?要进行正则匹配,我们需要调用其匹配的方法,有些匹配方式比如子串匹配,可能有多个结果,需要我们多次调用才能获得结果,可以理解为迭代器的流程,需要一步一步通知M原创 2020-08-09 23:46:23 · 2645 阅读 · 0 评论 -
【Java】同步/异步 vs 阻塞/非阻塞
今天看到一个回答,太精确了:https://www.zhihu.com/question/19732473第二条回答个人理解:这两个维度是两个完全不同的维度,处于不同层级。阻塞/非阻塞,侧重于api的实现形式,调用者调用后,是否是阻塞的。同步/异步,应该是更高一级的概念,是说调用结果的获取,是否需要调用者自己去主动获取。同步调用,调用者需要主动获取,可能是阻塞的也可能是非阻塞的。而异步则不需要,比如调用时提供回调函数,有结果了调用回调通知。...原创 2020-08-01 14:41:31 · 205 阅读 · 0 评论 -
【Java】okHttp3 简单使用
之前用的RestTemplate,发现一个multipart的http请求始终发不成功,后面就试了下okHttp,发现真的好用,api太清爽了,记录一下使用:package com.liyao;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import org.jetbrains.annotations.NotNull;import org.junit.Test;原创 2020-08-01 14:19:20 · 2528 阅读 · 0 评论 -
【Java】随机数原理 Random ThreadLocalRandom
大致生成原理:随机数由seed经过一定的转换生成。需要提供初始seed。每一次生成随机数时,先由老seed生成新seed,再根据新seed生成新的随机数。由于算法是固定的,所以如果初始seed一样,那么生成的随机数序列就是一样的,这就是为什么Java的随机数要被叫做“伪随机数”。数学逻辑这里不展开。主要实现类有两个Random以及ThreadLocalRandom。这两个都是线程安全的,区别在于解决并发生成新seed的方式不一样。Random是通过cas+自旋的方式,所以高并发场景下会有竞争,可能造成性能原创 2020-05-22 13:27:09 · 944 阅读 · 1 评论 -
【Jackson】@JsonCreator 注解
该注解用在对象的反序列时指定特定的构造函数或者工厂方法。在反序列化时,Jackson默认会调用对象的无参构造函数,如果我们不定义任何构造函数,Jvm会负责生成默认的无参构造函数。但是如果我们定义了构造函数,并且没有提供无参构造函数时,Jackson会报错:com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot c...原创 2020-04-30 13:47:08 · 23629 阅读 · 3 评论 -
【docker】Java应用 容器内存管理 -XX:+UseContainerSupport
早期时候,容器内运行Java应用程序时,Jvm无法感知容器环境存在,所以对容器资源的限制比如内存或者cpu等都无法生效。原因是容器的资源管理使用了操作系统cgroup机制,但是Jvm无法感知cgroup。所以可能需要在jvm以及docker中指定两次内存限制。后来,在Jvm9及以后,Jvm开始了对容器资源限制的支持。在Jvm11中,可以使用-XX:+UseContainerSupport参数来制定...原创 2020-04-18 15:15:38 · 9491 阅读 · 2 评论 -
【servlet】Servlet url-pattern, /与/*区别
servlet有自己的一套匹配规则。大致分三种,精确,路径和后缀。先说路径:以/开头且以/*结尾的是路径匹配,该路径下的所有url都会被匹配。如果可以匹配多个路径,那么以最长的为结果。后缀:*.xxx。固定写法,*前面不能有东西,不能和路径匹配一起用,比如/abc/*.txt是不允许的。有一种特殊的后缀匹配是“/*”,这个在所有的后缀匹配中优先级最高,可以匹配任何url。但是如果已经有精确匹配或者...原创 2018-04-18 23:36:32 · 663 阅读 · 0 评论 -
【SpringMVC(十七)】静态资源
在SpringMVC中,如果对静态资源不做特殊处理,如果找不到会返回404.原因是,我们在web.xml中会这样配置dispatcherServlet的url-pattern: <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/&l...原创 2020-04-06 19:17:28 · 534 阅读 · 0 评论 -
【SpringMVC(十六)】分片上传 例子
对于大文件的上传,客户端可以多线程分片上传,加快速率,服务端需要merge分片并存储。常见思路:通过status预上传接口获取一个key,再调用分片接口上传每一个分片,上传完调用publish接口完成上传。status接口的key用于串联整个过程。一个简单的示例:@RestController@RequestMapping("/rest/n/testApi")public c...原创 2020-04-05 20:27:36 · 269 阅读 · 0 评论 -
【SpringMVC(十五)】HttpRange 分片下载 断点续传
基于http协议实现断点续传。请求部分,需要在请求头里加入Range头,表示本次请求的byte数组的开始和结束位置。https://tools.ietf.org/html/rfc7233#section-3.1格式为:Bytes=开始-结束。如果不填表示0或者最后。对于要支持断点续传的服务器,需要处理这个请求头,如果发现有Range头部,需要对响应特殊处理。body:返回Ran...原创 2020-04-05 20:12:26 · 2833 阅读 · 0 评论 -
【SpringMVC(十四)】HttpMessageConverter
接口定义:public interface HttpMessageConverter<T> { boolean canRead(Class<?> clazz, @Nullable MediaType mediaType); boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType)...原创 2020-04-05 19:19:22 · 327 阅读 · 0 评论 -
【SpringMVC(十三)】ResponseEntity 使用 及 原理
使用ResponseEntity可以作为controller的返回值,比如对于一个处理下载二进制文件的接口,可以这么定义: @RequestMapping("/download") public ResponseEntity<byte[]> download(@RequestParam String fileName) throws IOException {...原创 2020-04-05 17:22:53 · 41249 阅读 · 1 评论 -
【Java】路径相关
1.非web项目通常将配置文件放在resources目录下。借助classloader,读取方式如下: Path path = Paths.get(App.class.getClassLoader().getResource("file/a.txt").getPath()); Files.lines(path).forEach(System.out::pri...原创 2020-04-05 00:02:39 · 111 阅读 · 0 评论 -
【Java】Files Paths 用法记录
摒弃File及InputStream那一套API。内存中二进制数据拷贝使用common-io的IoUtils类;内存-文件系统交互使用Java7中的Files以及Paths类。public class FileTest { private static final String fullPath = "/Users/miracle/Desktop/a/my.txt"; ...原创 2020-04-03 22:55:25 · 549 阅读 · 0 评论 -
【Java】翻页 cursor与page翻页
后端返回数据的接口需要翻页设计,防止客户端一次性请求大量数据。传统的方式是page+limit。通过page和limit可以计算出从哪里开始拿数据,以及需要拿多少条。另一种方式是cursor+limit。cursor是一个游标,可以是id或者时间戳等,总之可以唯一标识一条数据,并且存储时会按照该字段排序。每一次访问时带上前一次返回的cursor,服务端就返回cursor之后的limit条数据以及下...原创 2020-03-29 16:01:50 · 1941 阅读 · 2 评论 -
【Jackson】jackson map ClassCastException
考虑这个场景,我们在设计数据库表时,往往会加一个扩展字段列,可以是varchar类型。程序中可以将各种扩展字段放入一个map结构中,再序列化为string,存入数据库。下面以json作为序列化方式来看一个例子:比如下面Data类中的ext字段:public class Data { private long id; private String name; pr...原创 2020-03-29 15:36:17 · 388 阅读 · 0 评论 -
【Java】url encode
什么是url encode?url是一种资源定位符号,用于标识一个资源。url产生之初的一个想法是让url可以方便得传递,所以url的字符被限定ASCII码的一个集合内,这些被称为非限定字符集。除此之外,还有一些字符具有特定功能,比如query参数需要?来连接url和参数。多个参数需要用&来拼接等等。这些功能性的字符被称为保留字符。关于这些保留字符的含义,参见:http...原创 2020-03-22 19:34:47 · 3007 阅读 · 0 评论 -
【Java】wait notify 为什么放在同步块内
wait、notify和notifyAll三个方法必须放在同步块内执行。现象:如果不放在同步块内,运行时会抛出这个异常:IllegalMonitorStateException。原因:因为wait和notify(包括notifyAll,为了方便,后面仅写notify)的使用一般而言,都是成对的(自己等待,通知别人)。举一个生产者消费者的例子,大概是下面这样的模式:生产者p...原创 2020-02-09 12:53:28 · 704 阅读 · 0 评论 -
【Java】DelayQueue
一个无界的延迟队列,仅仅当队列内有元素到期时才能被取出。元素必须实现Delayed接口,用于判定元素是否到期。public interface Delayed extends Comparable<Delayed> { /** * Returns the remaining delay associated with this object, in the...原创 2020-02-03 16:36:25 · 134 阅读 · 0 评论 -
【Java】BlockingQueue
上一篇记录了Queue接口的相关定义:https://blog.csdn.net/u010900754这里再看一下其子接口BlockingQueue。该接口扩展了Queue接口,主要新提供了如下能力:1.从队首取元素时,如果队列为空,可以等待直到队列有元素;2.向队尾添元素时,如果队列已满,可以等待直到队列不满;本质上,BlockingQueue仍然是那三种操作,即添加,移除,...原创 2020-02-03 16:29:39 · 203 阅读 · 0 评论 -
【Java】Queue 接口
该接口继承自Collection,提供先进先出的接口,主要包了以下三种类型的操作:1.在队尾存;2.从队首取;3.查看队首;另外有两个维度,针对异常情况,一种是抛出异常,一种是返回特定的值;现以成对方式给出例子: private Queue<Integer> queue; @Before public void init0() { ...原创 2020-02-03 16:13:23 · 218 阅读 · 0 评论 -
【Java】线程池(七)Executors 线程池创建
Executors是一个线程池的工具类,方便我们创建各种各样的线程池。对于我们常用的线程池ThreadExecutorPool,提供了四种工厂方法。先回顾下ThreadExecutorPool构造函数吧: public ThreadPoolExecutor(int corePoolSize, int maximumPo...原创 2020-02-03 11:40:21 · 212 阅读 · 0 评论 -
【Java】线程池(六)线程池状态
* The runState provides the main lifecycle control, taking on values: * * RUNNING: Accept new tasks and process queued tasks * SHUTDOWN: Don't accept new tasks, but process q...原创 2020-02-02 19:44:44 · 182 阅读 · 0 评论 -
【Java】线程池(五)shutdown shutdownnow
以ExecutorService的实现类ThreadPoolExecutor为例,看下关于线程池管理方法的实原理:注意shutdown shutdownnow方法均不是阻塞的,仅仅完成状态的设置,不会等待任务执行完毕。1.shutdown:调用该方法后会拒绝接收新任务。 public void shutdown() { final ReentrantLock m...原创 2020-02-02 19:29:39 · 2370 阅读 · 0 评论 -
【Java】线程池(四)关闭线程池
如何优雅的关闭线程池?其实在java源代码注释里有:大致是先调用shutdown方法,然后再调用awaitTermination等待正在执行的任务的结束。如果在一段时间内仍未结束,再调用shutdownnow方法强制停止。guava的线程池库中有一个实现:MoreExecutors::shutdownAndAwaitTermination方法。 public static ...原创 2020-02-02 12:19:16 · 1464 阅读 · 0 评论 -
【Java】线程池(二)ExecutorService
先看其父接口Executor。public interface Executor { /** * Executes the given command at some time in the future. The command * may execute in a new thread, in a pooled thread, or in the call...原创 2020-02-02 11:37:12 · 149 阅读 · 0 评论 -
【Java】异常 打印
如何打印一个异常?分两种case吧。1.不使用日志框架,即简单的systemout方式。 public static void main(String args[]) { try { new Main().g(); } catch (Exception e) { System.out.println...原创 2020-01-31 17:41:55 · 844 阅读 · 0 评论 -
【Java】String 相关
1. String是不可变对象也就是说,一旦创建了一个string对象,其内容便无法修改。string对想内部持有了一个char数组的引用,这个char数组只能在构造函数中被初始化,string没有暴露任何接口来修改char数组的元素。 /** The value is used for character storage. */ private final char va...原创 2020-01-30 21:53:29 · 109 阅读 · 0 评论 -
【Java】ClientAbortException
这个异常怎么来的?大致看了下tomcat源码,是web容器里抛出的一个异常。/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this wor...原创 2020-01-28 11:50:26 · 1785 阅读 · 0 评论 -
【Java】布尔变量 序列化
java中对于布尔变量使用jackson序列化时需要注意变量命名。根据javabean规范,如果布尔变量名是p,则getter和setter方法分别为:isP和setP。如果按照上述规范来命名变量及getter和setter,那么json的序列化和反序列化都没有问题。但是如果,命名为isP,则默认的getter和setter方法还是isP和setP,这点需要额外注意。序列化后的变量...原创 2019-11-24 22:20:13 · 684 阅读 · 0 评论 -
【SpringMVC(十二)】@ControllerAdvice 异常处理 使用 及 原理
我们在写web应用时,有一个很常见的需求就是:业务层可能会抛出各种各样的异常,我们希望可以在最终接口返回时,根绝异常类型自动映射为一个errorcode以及errormsg,下发给客户端。具体看下:以登录为例,我们有一个userService,可以通过客户端的token反解出user信息。如果token不合法,则抛出一个业务异常,终止当前请求:@Servicepublic clas...原创 2019-11-02 14:38:13 · 866 阅读 · 0 评论 -
【SpringMVC(十一)】xml默认配置文件位置
今天想写一个springmvc的demo程序,但是一直在报找不到applicationContext.xml配置文件的错误。我当时将配置文件放在了classpath下,以为spring启动时默认是在classpath下寻找的,但是实际上不是,这里做一个记录。如果使用xml配置方式,那么默认会使用XmlWebApplicationContext类型的容器。该容器实现了loadBeanDefi...原创 2019-11-02 13:29:09 · 1380 阅读 · 0 评论