sleep、wait及park介绍

Thread.sleep(time) 该方法必须传入指定的时间,线程将进入休眠状态,通过jstack输出线程快照的话此时该线程的状态应该是TIMED_WAITING,表示休眠一段时间。 该方法会抛出InterruptedException异常,这是受检查异常,调用者必须处理。 通过sleep方法进入休眠的线程不会释放持有的锁,因此,在持有锁的时候调用该方法需要谨慎。 Object.wait() 方法 java的每个对象都隐式的继承了Object类。因此每个类都有自己的wait()方法。我们通过object.wait()方法也可以让线程进入休眠。wait()有3个重载方法: public final void wait() throws InterruptedException; public final

  • 凯文
8 min read
java

生产问题之CaffeineCache使用中的坑

问题描述 服务缓存中使用CaffeineCache时,通过CaffeineCache在数据更新并且超过refreshAfterWrite时间后首次获取缓存时,偶发性的获取不到最新的缓存 实现 public class CaffeineCacheTest { public static void main(String[] args) throws Exception { CaffeineCacheTest test = new CaffeineCacheTest(); Cache cache = test.caffeineCacheManager().getCache("test"); CacheObject cacheObject = (CacheObject) cache.get(

  • 凯文
3 min read
linux

linux上下文切换

上下文切换 CPU 上下文切换,就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。 上下文切换的类型 中断上下文切换 线程上下文切换 用户态内核态上下文切换 进程上下文切换 用户态内核态上下文切换 进程既可以在用户空间运行,又可以在内核空间中运行。进程在用户空间运行时,被称为进程的用户态,而陷入内核空间的时候,被称为进程的内核态。 从用户态到内核态的转变,需要通过系统调用来完成。比如,当我们查看文件内容时,就需要多次系统调用来完成:首先调用 open() 打开文件,

  • 凯文
5 min read
redis

分布式锁之redisson

使用redisson的原因 比zk性能要好 比使用redis.setnx的优势 使用redis.setnx时,如果系统挂掉,会一直锁住 redisson将ttl和set 通过lua脚本原子性批量执行 实现 Lock lock = redisson.getLock("test"); lock.lock(); 源码 RLock锁API public interface RLock { //----------------------Lock接口方法----------------------- /** * 加锁 锁的有效期默认30秒 */ void lock(); /** * tryLock()方法是有返回值的,它表示用来尝试获取锁,

  • 凯文
5 min read

响应式编程RxJava之Subject

概述 RxJava中常见的Subject有4种,分别是 AsyncSubject、 BehaviorSubject、 PublishSubject、 ReplaySubject。 一定要用Subcect.create()的方式创建并使用,不要用just(T)、from(T)、create(T)创建,否则会导致失效 AsyncSubject 简单的说使用AsyncSubject无论输入多少参数,永远只输出最后一个参数。 // 无论订阅的时候AsyncSubject是否Completed,均可以收到最后一个值的回调 AsyncSubject as = AsyncSubject.create(); as.onNext(1); as.onNext(2)

  • 凯文
3 min read
java

响应式编程RxJava之Single

简单入门 Single.just(T value); 通常使用RxJava,主要是为了异步处理一些任务。即传入一些值,经过逻辑处理之后返回结果。 以上代码中的just(T value),可以看作是传入参数。 有了输入,如何输出呢?我们讲到了异步处理,那自然得有一个异步回调才行吧,这简直理所应当吧。所以这里介绍最重要的"subscribe"概念。 Single.just(T value).subscribe(); 例如: int addValue(int a,

  • 凯文
8 min read
java

reactor响应式编程之 Mono & flux

Publisher 由于响应流的特点,我们不能再返回一个简单的POJO对象来表示结果了。必须返回一个类似Java中的Future的概念,在有结果可用时通知消费者进行消费响应。 Reactive Stream规范中这种被定义为Publisher<T> ,Publisher<T>是一个可以提供0-N个序列元素的提供者,并根据其订阅者Subscriber<? super T>的需求推送元素。一个Publisher<T>可以支持多个订阅者,并可以根据订阅者的逻辑进行推送序列元素。下面这个Excel计算就能说明一些Publisher<T>的特点。 Publisher&

  • 凯文
5 min read
java

响应式编程之RxJava VS Reactor

目前市场上比较流行的有几种,RxJava,Akka,Vert.x,Reactor。最常使用的两种框架,并且实现了响应式编程规范的是RxJava和Reactor。 两者之间有什么区别呢? API Flowable和FluxAPI很相似都支持,ReactiveX常见的那些操作符。map,filter,flatmap等等,具体操作符列表:http://reactivex.io/documentation/operators.html 在Java版本上: RxJava2.x必须至此Java 6,因为它Rxjava在安卓中用的很多 Reactor则至少要求Java 8. 其内部利用了很多新版Java的特性。并且还可以方便的转换为:CompletableFuture,java.

  • 凯文
4 min read
java

jvm类的加载及方法调用过程

类的加载过程 加载 加载是指查找字节流,并且据此创建类的过程。 加载需要借助类加载器,在 Java 虚拟机中,类加载器使用了双亲委派模型,即接收到加载请求时,会先将请求转发给父类加载器。 链接 验证:确保被加载类能够满足 Java 虚拟机的约束条件 准备:为被加载类的静态字段分配内存;部分 Java 虚拟机还会在此阶段构造其他跟类层次相关的数据结构,比如说用来实现虚方法的动态绑定的方法表 解析:将符号引用解析成为实际引用;如果符号引用指向一个未被加载的类,或者未被加载类的字段或方法,那么解析将触发这个类的加载(但未必触发这个类的链接以及初始化。) 初始化 常量值(ConstantValue)初始化直接由 Java

  • 凯文
7 min read

java基本数据类型

java基本数据类型介绍 在java中 false实际值为0 true为1 Java 的基本类型都有对应的值域和默认值。可以看到,byte、short、int、long、float 以及 double 的值域依次扩大,而且前面的值域被后面的值域所包含。因此,从前面的基本类型转换至后面的基本类型,无需强制转换。另外一点值得注意的是,尽管他们的默认值看起来不一样,但在内存中都是 0。 在 Java 中,正无穷和负无穷是有确切的值,在内存中分别等同于十六进制整数 0x7F800000 和 0xFF800000。0x7F800001 对应的浮点数是

  • 凯文
4 min read
java

Java 虚拟机执行Java 字节码过程

Java 虚拟机具体是怎样运行 Java 字节码的 java类加载 从虚拟机视角来看,执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机中。加载后的 Java 类会被存放于方法区(Method Area)中。实际运行时,虚拟机会执行方法区内的代码。 如果你熟悉 X86 的话,你会发现这和段式内存管理中的代码段类似。而且,Java 虚拟机同样也在内存中划分出堆和栈来存储运行时数据。 不同的是,Java 虚拟机会将栈细分为面向 Java 方法的

  • 凯文
5 min read

业务日志收集

问题 当服务qps过高时,如果收集业务日志时直接写入kafka可能会导致接口延时上升,另外直接写入的日志不一定可直接使用,需要经过fink过滤处理,固采用以下方式收集海量的业务日志 服务将日志通过 log的方式写入碰盘文件,可异步写,降低io次数 有专门的agent采集文件日志,并写入kafka 将kafka的数据传输至flink中进行过滤处理,然后再导入另一个kafka topic 读取新的kafka topic数据,写入hive或 es

  • 凯文
1 min read

记录一次上线前压测过程

首次压测 95及99分位极度不稳 去掉CheckUtil 查看服务日志,发现某个trace CheckUtil耗时长,去掉该功能后压测 根据查看gc情况无关,而和jvm垃圾回收有关 查看gc情况 定位gc有问题,调整jvm参数 调整jvm参数 xmn8g 99分位稳定 问题:为什么年轻代自适应 未生效 AdaptiveSizePolicy调整的是 Eden、From 和 To 区的大小 并不会调整 年轻代的大小 年轻代过大,会不会导致回收时间过长 垃圾回收主要耗时点在于copy的过程,而扫描的过程是很快的,针对该场景,由于是qps高导致大量对象在年轻代回收,所以需要copy的对象是很少的,

  • 凯文
2 min read
linux

linux之lsof

lsof命令是什么? 可以列出被进程所打开的文件的信息。被打开的文件可以是 普通的文件 目录 网络文件系统的文件 字符设备文件 (函数)共享库 管道,命名管道 符号链接 底层的socket字流,网络socket,unix域名socket 在linux里面,大部分的东西都是被当做文件的…..还有其他很多 lsof使用 列出所有打开的文件: lsof 备注: 如果不加任何参数,就会打开所有被打开的文件,建议加上一下参数来具体定位 查看谁正在使用某个文件 lsof /filepath/file 递归查看某个目录的文件信息 lsof +D /filepath/

  • 凯文
2 min read
java

java-mysql时区问题

问题 数据库时间展示正常,但是web页面时间与数据库时间差 13/14 个小时 原因 mysql采用的是CST时区,而java使用的是北京时间,两个时区有时差13个小时有时差14个小时,故从数据库查出数据后,如果直接展示无问题,但是如果通过java程序 SimpleDateFormat转换,就会出现问题 解决方案 在通过SimpleDateFormat转换时间时,设置时区为 CST 此方案,后续所有使用SimpleDateFormat转换数据库时间时,都需要指定TimeZone 但是通过SimpleDateFormat转换非数据库date(如 当前date)时,不需要指定TimeZone format.setTimeZone(TimeZone.getTimeZone("CST&

  • 凯文
1 min read
linux

主板频率、内存频率与cpu频率

频率与超频 【频率】电子元件工作的时候会运行在一定的频率下,频率越高,这个元件的处理速度越快,这就和汽车发动机的马力一样,但是在电脑中,性能不单单只是由频率这一项参数决定,所以频率仅限相同的产品,同一代进行横向对比。 【超频】电子元件既然会照着一定的频率运行,这个频率肯定不是凭空而来,他是厂家在出厂的时候人为设定的,厂家会将频率设定在一个能长期稳定运行的状态下,既然频率是人为设定的,那我们也可以去人为更改,将默认的频率手动修改到更高,让元件超负荷运转,这就是俗称的超频,由于频率高了,电压与发热也会变高,因此超频虽然能免费提升性能,但也要承担相应风险。 内存条的标注频率 内存条的标注频率指的就是你在买内存的时候,商品标题所写的内存频率,这个就是代表了内存条的物理属性。 内存条的标注频率代表了这个内存最高可以稳定工作在什么样的频率下,这里有两个关键词就是最高和稳定,内存频率是人为设定的,只要你想,2400的内存同样可以设定为3200,

  • 凯文
6 min read
java

synchronized详解

问题 某实例未执行过锁代码块,该实例的标识位是101还是001? 轻量级锁和重量级锁执行完成锁代码块后的标识位分别是什么? 轻量级锁执行完锁代码块后,出现其他线程竞争锁,该线程竞争成功后是什么锁? synchronized是否可降级? java对象Mark Word 32位Header Mark Word 即32bit,4个字节 64位Header Mark Word |------------------------------------------------------------------------------|--------------------| | Mark Word (64 bits) | State | |------------------------------------------------------------------------------|--------------------| | unused:25 | identity_hashcode:31 | unused:

  • 凯文
9 min read
java

java基础之二进制存储

原码、反码和补码 在计算机内,定点数有3种表示法:原码、反码和补码 原码 二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。 反码 正数的反码与其原码相同; 负数的反码是对其原码逐位取反,但符号位除外;即对其原码的绝对值取反,如 10001010的反码为11110101 补码 正数的补码与其原码相同;负数的补码是在其反码的末位加1。 byte jvm byte存储方式 Java中用补码表示二进制数,补码的最高位是符号位,最高位为“0”表示正数,最高位为“

  • 凯文
3 min read