java
文章平均质量分 83
java技术
风筝Lee
儿时,你是父母手中的风筝;上学了,你是老师手中的风筝;工作了,你是领导手中的风筝;成家了,你是妻子手中的风筝;老时,你是子女手中的风筝。人生就像风筝,总有一根线牵着你,或长、或短,或紧、或松;你在这头,爱你的人就在那头。
展开
-
OpenJDK ZGC 源码分析(二)触发GC的时机
1. 简介ZGC的回收周期触发时机与其他GC算法略有不同,VM内部有个线程轮询定期检查是否满足开始回收的条件,如果满足则开始回收。ZGC提供四种策略,其中一种满足条件即触发回收:rule_timer,定时策略,距离上次GC时间超过interval即触发GC rule_warmup,VM启动后,如果从来没有发生过GC,则在堆内存使用超过10%、20%、30%时,分别触发一次GC,以收集GC数据 rule_allocation_rate,根据对象分配速率决定是否GC rule_proactiv转载 2021-03-31 11:24:41 · 767 阅读 · 0 评论 -
OpenJDK ZGC 源码分析(一)概览
1. 前言G1是JDK中最新最成熟的垃圾回收器,其稳定性和性能得到了广泛的认可。但是,一方面随着硬件的发展,堆空间越来越大,几十GB、上百GB的内存在生产环境逐渐出现;另一方面,对于停顿时间的需求日益严苛,从最初的秒级到百毫秒级,再到十毫秒级和毫秒级。G1对于这种情况逐渐力不从心,下一代低延迟垃圾回收器主要有ZGC和Shenandoah。本文将详细介绍ZGC相关原理。2. 历史Oracle在2017年将ZGC贡献给OpenJDK社区。在JDK 11中作为实验性功能加入(JEP 333: ZG转载 2021-03-31 10:50:31 · 441 阅读 · 0 评论 -
ParNew收集器复习
以下摘自:《深入理解Java虚拟机:JVM高级特性与最佳实践》第3章垃圾收集器与内存分配策略ParNew收集器其实就是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数(例如:-XX:SurvivorRatio、 -XX:PretenureSizeThreshold、-XX:HandlePromotionFailure等)、收集算法、Stop The World、对象分配规则、回收策略等都与Serial收集器完全一样,实现上这两种收集器也共转载 2021-02-22 15:41:28 · 209 阅读 · 0 评论 -
读写锁饥饿问题解决方案之StampedLock
引言ReentrantReadWriteLock可以让多个读线程同时持有读锁(只要写锁未被占用),而写锁是独占的,所以在读多写少的场景上可以提高吞吐量,比如hdfs文件系统。但是,读写锁如果使用不当,很容易产生“饥饿”问题,比如在读线程非常多,写线程很少的情况下,很容易导致写线程“饥饿”,虽然使用“公平”策略可以一定程度上缓解这个问题,但是“公平”策略是以牺牲系统吞吐量为代价的。导致写线程饥饿的情况:当线程 A 持有读锁读取数据时,线程 B 要获取写锁修改数据就只能到队列里排队。此时又来了线程 C原创 2020-12-09 22:23:25 · 3755 阅读 · 3 评论 -
StampedLock原理分析
背景ReentrantReadWriteLock可以让多个读线程同时持有读锁(只要写锁未被占用),而写锁是独占的,所以在读多写少的场景上可以提高吞吐量,比如hdfs文件系统。但是,读写锁如果使用不当,很容易产生“饥饿”问题,比如在读线程非常多,写线程很少的情况下,很容易导致写线程“饥饿”,虽然使用“公平”策略可以一定程度上缓解这个问题,但是“公平”策略是以牺牲系统吞吐量为代价的。导致写线程饥饿的情况:当线程 A 持有读锁读取数据时,线程 B 要获取写锁修改数据就只能到队列里排队。此时又来了线程 C转载 2020-12-08 23:53:41 · 1145 阅读 · 1 评论 -
Class.forName 和 ClassLoader 到底有啥区别?
在java中Class.forName()和ClassLoader都可以对类进行加载。ClassLoader就是遵循双亲委派模型最终调用启动类加载器的类加载器,实现的功能是“通过一个类的全限定名来获取描述此类的二进制字节流”,获取到二进制流后放到JVM中。Class.forName()方法实际上也是调用的CLassLoader来实现的。Class.forName(String className);这个方法的源码是@CallerSensitive public static Class<转载 2020-09-17 15:01:02 · 148 阅读 · 0 评论 -
java复习之重载和重写
Java 重写(Override)与重载(Overload)重写(Override)重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exceptio转载 2020-07-28 14:31:25 · 198 阅读 · 0 评论 -
java集合复习整理
一. ArrayList和LinkedList区别1. 是否保证线程安全: ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;2. 底层数据结构: Arraylist 底层使用的是Object数组;LinkedList 底层使用的是双向链表数据结构(JDK1.6之前为循环链表,JDK1.7取消了循环。注意双向链表和双向循环链表的区别,下面有介绍到!)3. 插入和删除是否受元素位置的影响: ① ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元.原创 2020-07-28 14:05:22 · 191 阅读 · 0 评论 -
Java JNI实现原理解析
前言本篇文章主要从几个方面来阐述下javajni的原理机制。1.什么是javajni? 2.javajni有什么作用? 3.javajni应用场景有哪些?4.javajni实现原理5.javajni如何使用;6.使用实例;下面我们逐一进行解析。什么是javajniJNI(JavaNativeInterface)是JAVA标准平台中的一个重要功能,它弥补了JAVA的与平台无关这一重大优点的不足,在JAVA实现跨平台的同时,也能与其它语言(如C、C++)的动态库进...原创 2020-07-23 22:59:45 · 1918 阅读 · 0 评论 -
从 volatile 说起,可见性和有序性是什么
并发的三个特性首先说我们如果要使用 volatile 了,那肯定是在多线程并发的环境下。我们常说的并发场景下有三个重要特性:原子性、可见性、有序性。只有在满足了这三个特性,才能保证并发程序正确执行,否则就会出现各种各样的问题。原子性, CAS 和 Atomic* 类,可以保证简单操作的原子性,对于一些复杂的操作,可以使用synchronized 或各种锁来实现。可见性,指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。有序性,程序执行的顺序按照代码的先转载 2020-07-23 15:28:54 · 673 阅读 · 0 评论 -
java对象锁和类锁
最近发现有很多初学java多线程基础的同学会问到对象锁和类锁会相互影响吗,本篇文章首先介绍下对象锁和类锁,然后从基础原理角度说明下具体关系。对象锁(实例锁)我们知道,类声明后,我们可以 new 出来很多的实例对象。这时候,每个实例在 JVM 中都有自己的引用地址和堆内存空间,这些实例都是独立的个体,很显然,在实例上加的锁和其他的实例就没有关系,互不影响了。所以使用对象锁的情况,只有使用同一实例的线程才会受锁的影响,多个实例调用同一方法也不会受影响。通常我们使用实例锁的方式有下面三种:..转载 2020-07-23 14:20:04 · 932 阅读 · 0 评论 -
类加载器ClassLoader
引言当刚学 c/c++ 程序时,第一次在控制台下运行程序,需要将所有程序文件进行编译、链接,然后再运行。这很容易理解,毕竟我在一段程序中引用了另一个文件中定义的函数,当然要把这些文件连接到一起。但是在运行 java 程序时却不需要这么做了,顶多在运行时加一个 -classpath 参数。这背后的原因就是 jvm 和 java 中的 ClassLoader 机制。类装载流程首先介绍下类装载流程,主要包括加载、连接、初始化;1、加载加载是类装载的第一步,首先通过class文件的路径.转载 2020-07-23 13:25:18 · 585 阅读 · 0 评论 -
Java并发编程-Synchronized实现原理
目录:1.Synchronized介绍2.实现原理解析一.Synchronized介绍Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。Synchronized的作用主要有三个:(1)确保线程互斥的访问同步代码(2)保证共享变量的修改能够及时可见(3)有效解决重排序问题。Java中每一个对象都可以作为锁,这是synchronize...转载 2019-06-10 10:02:53 · 115 阅读 · 0 评论 -
Java里的CompareAndSet(CAS)
Atomic从JDK5开始, java.util.concurrent包里提供了很多面向并发编程的类. 使用这些类在多核CPU的机器上会有比较好的性能.主要原因是这些类里面大多使用(失败-重试方式的)乐观锁而不是synchronized方式的悲观锁.跟踪一下AtomicInteger的incrementAndGet的具体实现:首先可以看到他是通过一个无限循环(spin)直到incre...转载 2019-04-01 14:16:21 · 1897 阅读 · 0 评论 -
避免出现空指针异常方法总结(java篇)
Java应用中抛出的空指针异常是解决空指针的最好方式,也是写出能顺利工作的健壮程序的关键。避免Java中的空指针异常的常用技巧(同时避免大量的非空检查):1) 从已知的String对象中调用equals()和equalsIgnoreCase()方法,而非未知对象。总是从已知的非空String对象中调用equals()方法。因为equals()方法是对称的,调用a.equals(b)和调...转载 2019-03-27 11:24:56 · 4433 阅读 · 0 评论 -
问题研究-Cannot refer to the non-final local variable a defined in an enclosing scope
问题:在java线程中使用局部变量时候经常编译器会提示:Cannot refer to the non-final local variable a defined in an enclosing scope(局部变量必须声明为final)由于方法中的形参i没有声明为final,编译抛出异常:Cannot refer to the non-final local variable a de...原创 2019-03-27 11:01:26 · 14984 阅读 · 0 评论 -
JVM内存模型
一·背景计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁盘和CPU的交互,而CPU运转速度越来越快,磁盘远远跟不上CPU的读写速度,才设计了内存,用户缓冲用户IO等待导致CPU的等待成本,但是随着CPU的发展,内存的读写速度也远远跟不上CPU的读写速度,因此,为了解决这一纠纷,CPU厂商在每颗CPU上加入了高速缓存,用来缓解这种症状,因此,现在CPU同内存交互如下图所示。...翻译 2019-03-19 12:25:27 · 128 阅读 · 0 评论 -
AtomicInteger原理
前言:在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的方式进行加减操作。AtomicInteger是对int类型的一个封装,提供原子性的访问和更新操作,其原子性操作的实现是基于CAS(compare-and -swap)技术。本篇文章主要从源码上去分析下AtomicInteger...原创 2020-03-25 16:13:34 · 346 阅读 · 0 评论 -
java多线程面试总结
1. 什么是线程安全如果你的代码在多线程下执行和在单线程下执行永远都能获得一样的结果,那么你的代码就是线程安全的。这个问题有值得一提的地方,就是线程安全也是有几个级别的:1)不可变像String、Integer、Long这些,都是final类型的类,任何一个线程都改变不了它们的值,要改变除非新创建一个,因此这些不可变对象不需要任何同步手段就可以直接在多线程环境下使用2)绝对线程...原创 2019-10-09 19:14:16 · 102 阅读 · 0 评论 -
java多线程面试题总结
1. 进程和线程的区别一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不同的类和程序的单一进程。线程可以被称为轻量级进程。线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源。2. 多线程编程的好处是什么?在多线程程序中,多个线程被并发的执行以提高程序的效率,CPU不...转载 2019-10-09 18:51:05 · 182 阅读 · 0 评论 -
java并发编程之cas
目录1.CAS操作介绍2.CAS实现原理一. CAS操作介绍CAS (CompareAndSwap):在计算机科学中,比较和交换是用于实现多线程同步的原子指令。 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 这是作为单个原子操作完成的。 原子性保证新值基于最新信息计算; 如果该值在同一时间被另一个线程更新,则写入将失败。...原创 2019-07-02 14:39:03 · 162 阅读 · 0 评论 -
Java指令重排序与happens-before法则
目录:1.指令重排序2.happens-before法则一.指令重排序Java语言规范规定了JVM线程内部维持顺序化语义,也就是说只要程序的最终结果等同于它在严格的顺序化环境下的结果,那么指令的执行顺序就可能与代码的顺序不一致。这个过程通常叫做指令的重排序。指令重排序存在的意义在于:JVM能够根据处理器的特性(CPU的多级缓存系统、多核处理器等)适当的重新排序机器指令,...原创 2019-07-01 14:52:12 · 316 阅读 · 0 评论 -
java内存屏障的原理与应用
目录1.java内存屏障2.java内存屏障的使用一.java内存屏障1.1 什么是内存屏障(Memory Barrier)?内存屏障(memory barrier)是一个CPU指令。基本上,它是这样一条指令: a) 确保一些特定操作执行的顺序; b) 影响一些数据的可见性(可能是某些指令执行后的结果)。编译器和CPU可以在保证输出结果一样的情况下对指令重排序,使性能得...转载 2019-07-01 10:37:28 · 19389 阅读 · 10 评论 -
深入Java底层(一):内存屏障与JVM并发详解
目录1.内存屏障2.本文介绍了内存屏障对多线程程序的影响,同时将研究内存屏障与JVM并发机制的关系,如易变量(volatile)、同步(synchronized)和原子条件式(atomic conditional)。一.内存屏障内存屏障,又称内存栅栏,是一组处理器指令,用于实现对内存操作的顺序限制。本文假定读者已经充分掌握了相关概念和Java内存模型,不讨论并发互斥...转载 2019-06-24 17:59:23 · 1225 阅读 · 1 评论 -
Java lock的使用--复习篇
目录:1.java lock介绍2.java lock的使用一. javalock介绍:并发场景中,最简单的方式是直接添加同步关键字synchronized来实现多线程之间的同步互斥操作。另外一种高效的机制去完成”同步互斥”操作是使用Lock对象,比synchronized关键字更为强大功能,并且有嗅探锁定,多路分支等功能。在java.util.concurrent....原创 2019-06-10 10:56:53 · 290 阅读 · 0 评论 -
DisableExplicitGC和Direct ByteBuffer研究
目录:1. DisableExplicitGC介绍2.Direct ByteBuffer介绍一,DisableExplicitGC介绍-XX:+DisableExplicitGC标志自动将System.gc()调用转换成一个空操作,就是应用中调用System.gc()会变成一个空操作。最主要的原因是为了防止某些手贱的同学在代码里到处写System.gc()的调用而干扰了程...转载 2019-06-04 17:37:45 · 1280 阅读 · 0 评论 -
Shenandoah GC:一个来自JDK12的全新并发压缩垃圾回收器
是不是才听说了JDK11的ZGC,并且还没搞懂?不好意思,OpenJDK12马不停蹄的带来了Shenandoah GC。概述JDK12新增的一个名为Shenandoah的GC算法,它的evacuation阶段工作能通过与正在运行中Java工作线程同时进行(即并发,concurrent),从而减少GC的停顿时间。Shenandoah的停顿时间和堆的大小没有任何关系,这就意味着无论你的堆是...转载 2020-04-26 14:48:47 · 326 阅读 · 0 评论 -
设计模式六大原则
设计模式六大原则:单一原则、里氏替换原则、依赖倒置原则、接口隔离、迪米特原则、开闭原则;1.单一原则(Single Responsibility Principle):一个类或者一个方法只负责一项职责,尽量做到类的只有一个行为原因引起变化;业务对象(BO business object)、业务逻辑(BL business logic)拆分;2.里氏替换原则(LSP liskov substitution principle):本质是指多态性,子类可以扩展父类的功能,但不能改...原创 2020-06-24 10:30:26 · 178 阅读 · 0 评论 -
设计模式六大原则:开闭原则
开闭原则(Open Close Principle):Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. 软件对象(类、模块、方法等)应该对于扩展是开放的,对修改是关闭的。比如:一个网络模块,原来只有服务端功能,而现在要加入客户端功能,那么应当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,转载 2020-06-24 10:25:59 · 215 阅读 · 0 评论 -
最小堆原理与实现
基本概念:1、完全二叉树:若二叉树的深度为h,则除第h层外,其他层的结点全部达到最大值,且第h层的所有结点都集中在左子树。2、满二叉树:满二叉树是一种特殊的的完全二叉树,所有层的结点都是最大值。定义:1、堆是一颗完全二叉树;2、堆中的某个结点的值总是大于等于(最大堆)或小于等于(最小堆)其孩子结点的值。3、堆中每个结点的子树都是堆树。最大堆,最小堆类似,以下以最小堆为例进行讲解。最小堆是满足以下条件的数据结构:它是一棵完全二叉树;所有父节点的值小于或等于两个子节点转载 2020-06-22 13:59:58 · 14681 阅读 · 3 评论 -
常见排序算法的总结 - 复杂度、实现和稳定性
最基础的算法问题,温故知新。排序算法的几个主要指标是,时间复杂度(最好,最差和平均),空间复杂度(额外空间)和稳定性。本文主要描述八种常见算法:简单选择排序、冒泡排序、简单插入排序、希尔排序、归并排序、快速排序、堆排序和基数排序,关于它们的指标统计可以直接看最后。值得一提的是排序算法的稳定性,之前关注较少。稳定性的意思是对于序列中键值(Key value)相同的元素,它们在排序前后的相对关系保持不变。对于int这样的基本数据类型,稳定性基本上是没有意义的,因为它的键值就是元素本身,两个元素的键值相同他们转载 2020-06-07 23:00:04 · 383 阅读 · 0 评论 -
RDBMS架构:B+树实现范围查询(Range Scan)
本文记录了基于B+树架构的关系型数据库中,是如何实现Range Scan功能的。设计时,B+树每个节点是一个page;所有key存储在叶子节点;内部节点完全是索引所用。B+树服从左节点 < 父节点 < 右节点;最底层叶子节点严格按照从小到大顺序排列。补充:Tree based,有序,支持点查询和范围查询(Range Scan);Hash based,无序,只支持点查询。References:[1] 陈世敏老师的《大数据管理系统与大规模数据分析》课程讲义...转载 2020-06-07 21:54:42 · 1224 阅读 · 0 评论 -
Java匿名内部类
内部类:在一个类中定义另一个类,这样定义的类称为内部类。【包含内部类的类可以称为内部类的外部类】 如果想要通过一个类来使用另一个类,可以定义为内部类。【比如苹果手机类,苹果手机类中的黄金版的是特别定制的】 内部类的外部类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外部类中的方法。【不论是静态还是非静态的,内部类都可以直接调用外部 内部类的类体中不可以声明类变量和类方法 内部类可以由外部类使用外部类中在函数中创建内部类对象来使用,如果内部类的权限是非私有,非静态的,就可以在外部其他程序中原创 2020-06-07 10:21:15 · 190 阅读 · 0 评论 -
Java-RandomAccess源码分析
标记接口,Marker interface,它们是一类没有定义任何接口方法的接口,表现为一个空接口没有接口方法意味着实现该接口的类无需实现任何接口方法,仅仅作为一种标记,以供其他方法判断作用就是当某个类实现这个接口后即拥有了这个接口的功能,Java 虚拟机在运行时会识别到它标记接口是Java的语言特性RandomAccess在计算机科学中,随机访问(RandomAccess)是从大量的可寻址元素的数据中访问任何元素大致和访问其他元素一样简洁有效,不管多少元素在这个集合中。与随机访问相反的是.转载 2020-05-21 16:06:46 · 187 阅读 · 0 评论 -
java、大数据相关面试题总结
一.java并发1.concurrenthashmap实现原理;2.Semaphore实现原理;3.AQS实现原理;4.javanio实现原理;5.java线程InterruptedException的理解;6.java8stampedlock实现原理;二.数据结构1.二叉树遍历;层序、深度优先、广度优先、前中后序遍历;2.链表反转、判断是否有环;3.Btree 、B+tree;4.平衡二叉树、红黑树;三.算法...原创 2020-05-21 15:25:32 · 306 阅读 · 0 评论 -
Java序列化进阶:Java内置序列化的三种方式
Java序列化就是把Java对象按照一定的格式存到文件或者磁盘当中,那么Java内置的序列化有几种方式呢?每种方式的相同点和不同点是什么呢?序列化的进阶:即三种方式,任何一种方式都可以进行序列化和反序列化第一种使用默认的序列化机制,即实现Serializable接口即可,不需要实现任何方法。该接口没有任何方法,只是一个标记而已,告诉Java虚拟机该类可以被序列化了。然后利用ObjectOutputStream进行序列化和用ObjectInputStream进行反序列化。注意:该方式下转载 2020-05-20 17:52:14 · 215 阅读 · 0 评论 -
public/private/protected的具体区别
要继承使用的话要用protected声明。 (子孙类也可以用)。1、public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用2、private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用。3、protected:protected对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。扩展资料:三种类型的继承,父类的成员均被子类继承转载 2020-05-20 14:24:45 · 268 阅读 · 1 评论 -
JAVA多线程之中断机制
一,介绍这篇文章主要记录使用 interrupt() 方法中断线程,以及如何对InterruptedException进行处理。感觉对InterruptedException异常进行处理是一件谨慎且有技巧的活儿。由于使用stop()方法停止线程非常的暴力,人家线程运行的好好的,突然就把人家杀死了,线程占用的锁被强制释放,极易导致数据的不一致性。可参考这篇文章对stop()方法的介绍。因此,提出了一种温和的方式:请求另外一个线程不要再执行了,这就是中断方式。二,中断及如何响应中断?如.转载 2020-05-20 11:11:50 · 213 阅读 · 0 评论 -
java主线程捕获子线程异常方式梳理
前言:线程设计的理念:“线程的问题应该线程自己本身来解决,而不要委托到外部。”,正常情况下,如果不做特殊的处理,在主线程中是不能够捕获到子线程中的异常的,需要通过一些方式来实现。本篇文章主要研究下java子线程的异常处理机制和主线程捕获子线程异常的方式。原理分析:首先明确线程代码的边界。其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界。而所有的具体线程都实现这个方法,所以这里就明确了一点,线程代码不能抛出任何checked异常。所有的线程中的check.转载 2020-05-20 10:36:19 · 4603 阅读 · 1 评论 -
Java 理论与实践---处理 InterruptedException
捕捉到它,然后怎么处理它?这样的情景您也许并不陌生:您在编写一个测试程序,程序需要暂停一段时间,于是调用Thread.sleep()。但是编译器或 IDE 报错说没有处理检查到的InterruptedException。InterruptedException是什么呢,为什么必须处理它?对于InterruptedException,一种常见的处理方式是 “生吞(swallow)” 它 —— 捕捉它,然后什么也不做(或者记录下它,不过这也好不到哪去)—— 就像后面的清单 4一样。不幸的是,...转载 2020-05-19 14:37:25 · 282 阅读 · 0 评论