JDK

高级开发必须理解的Java中SPI机制

霸气de小男生 提交于 2021-01-17 02:57:50
本文通过探析JDK提供的,在开源项目中比较常用的Java SPI机制,希望给大家在实际开发实践、学习开源项目提供参考。 1 SPI是什么 SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。 整体机制图如下: Java SPI 实际上是“ 基于接口的编程+策略模式+配置文件 ”组合实现的动态加载机制。 系统设计的各个抽象,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 Java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。所以SPI的核心思想就是 解耦 。 2 使用场景 概括地说,适用于: 调用者根据实际使用需要,启用、扩展、或者替换框架的实现策略 比较常见的例子: 数据库驱动加载接口实现类的加载 JDBC加载不同类型数据库的驱动 日志门面接口实现类加载 SLF4J加载不同提供商的日志实现类 Spring Spring中大量使用了SPI,比如:对servlet3

两道JVM面试题,竟让我回忆起了中学时代!

☆樱花仙子☆ 提交于 2021-01-16 13:24:33
中学授课模式 考虑到可能有部分粉丝对JVM参数不清楚,所以我们参照中学的授课模式,给大家做一些知识上的普及。理论上,JVM参数主要分为三类 1.标配参数 该类型参数在JDK各个版本之间稳定,很少有大的变化。比如查看版本号 java -version 2.X参数 这些用的不多,看看就好。 // 解释执行 -Xint // 第一次使用就编译成本地代码 -Xcomp // 混合模式 -Xmixed 3.XX参数 3.1 布尔类型 -XX:+ 或者 - 某个属性值 ,+ 表示开启,-表示关闭。例如: // 打印GC详细信息 -XX:+PrintGCDetails // 不打印GC详细信息 -XX:-PrintGCDetails 3.2 KV类型 -XX:属性key=属性值value ,例如 // 设置Metaspace的大小 -XX:MetaspaceSize= 1024 m 中学考试试题 好了,现在课讲完了,那么我们来两道经典的JVM面试题。 填空题 在线上生产环境,JVM的 Xms 和 Xmx 一般设置成 _____ 比例。原因是 ____________ 。 选择题 我们常设置的JVM参数 Xms 和 Xmx ,属于下列哪种类型的JVM参数? A.标配参数 B.X参数 C.XX参数 D.以上均不是 解答 大家看这两道题,是不是有中学试卷的味道?上课教的东西,到了考试就全变样了

Java期末总结

﹥>﹥吖頭↗ 提交于 2021-01-16 06:00:36
经过这一学期对java的学习,对java已经能够初步运用,就是有些有点不记得,得看书或网上查阅使用方法。 相较C语言,java还是有很多大不同之处,却也有着许多相似之处 我也就本学期所学总结一下: 1、先了解java并搭建开发环境jdk。 2、关键字this、static、super、final、instanceof、throw和throws。 this: (1)表示类中的属性; (2)可以使用this调用本类的构造方法; (3)this表示当前对象; (4)用this强调本类中的方法。 static: (1)使用static声明属性; (2)使用static声明方法。 super:使用super调用父类中的指定构造方法(语句必须放在子类构造方法的首行)。 final: (1)使用final声明的类不能有子类; (2)使用final声明的方法不能被子类所覆写; (3)使用final声明的变量即成为常量,常量不可以修改。 instanceof:用来判断一个对象到底是哪个类的实例。 throws:在定义一个方法的时候可以使用throws关键字声明,使用throws声明的方法表示此方法不处理异常,而交给方法的调用处处理。 throw:与throws关键字不同的是,可以直接使用throw关键字抛出一个异常。抛出时直接抛出异常类的实例化对象即可。 3、java中线程的实现: (1

GMT UTC CST ISO 夏令时 时间戳,都是些什么鬼?

霸气de小男生 提交于 2021-01-15 19:08:50
你好,我是A哥(YourBatman)。 日期/时间的处理是平时开发中非常常见的场景,若只是简单的格式化场景那就还好,一旦涉及到时区、跨地域跨时区时间转换场景,甚至当还有GMT时间、UTC时间等一堆概念堆上来的时候,总是心理发虚,招架不住。 在地球村的信息化时代背景下,跨国企业/跨国做生意的公司越来越多,所以我们程序员遇到不同时区之间的日期/时间转换/显示的概率大大增加。譬如说:电商平台的商品下单时间,你给中国人页面里展示北京时间是ok的,但你总不能给美国人也展示北京时间吧?否则美国人看到很多订单的下单时间是凌晨1、2点,还以为午夜凶铃呢。 Java在版本8之前用Date类型来表示日期/时间,自版本8起引入了JSR 310日期/时间类型。两套体系对于本地时间、时区时间、带时区的格式化都有着不同的处理办法。 A哥因为跨时区日期转换问题,最近搞了一起 生产事故 ,为此我痛定思痛,决定把经验整理成文,目的是以后再也不踩这方面的坑,同时也帮助大家。 本部分一共会分两篇文章叙述: 概念篇:科普GMT、UTC、时区、时间戳、夏令时等常见概念以及背景 实战篇:在1的基础上(概念必须先知晓,否则实战无法进行),Java是如何来处理GMT/UTC时间、时区、偏移量、夏令时...的 这两篇文章搞完,自己再也不用不担心在日期/时间方面埋bug了。 相信我,这两篇文章十分具有收藏价值 。 本文提纲

tomcat性能调优和性能监控(visualvm)

和自甴很熟 提交于 2021-01-15 16:35:13
tomcat服务器优化 1、JDK内存优化 根据服务器物理内容情况配置相关参数优化tomcat性能。当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃。因此一般建议堆的最大值设置为可用内存的最大值的80%。 Tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大. Tomcat默认可以使用的内存为128MB,Windows下,在文件/bin/catalina.bat,Unix下,在文件 /bin/catalina.sh 的前面,增加如下设置: JAVA_OPTS='-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】 -XX:PermSize=64M -XX:MaxPermSize=128m' 需要把几个参数值调大。例如: JAVA_OPTS='-Xms256m -Xmx512m' 表示初始化内存为256MB,可以使用的最大内存为512MB。 参数详解 -server 启用jdk 的 server 版; -Xms java虚拟机初始化时的最小内存; -Xmx java虚拟机可使用的最大内存; -XX:PermSize 内存永久保留区域 -XX:MaxPermSize 内存最大永久保留区域 -Xmn jvm最小内存 32G 内存配置示例: JAVA_OPTS="$JAVA_OPTS -Xms10g

还没用上 JDK 12 ?JDK 13 已经可以下载了

生来就可爱ヽ(ⅴ<●) 提交于 2021-01-15 15:36:48
继 JDK12 GA 版本发布不久,OpenJDK 社区 4月18日 发布了 JDK13 Early Access 版本。 提供 Linux/macOS/Windows/Alpine Linux 平台下载,遵循 GNU GPL2 协议。 > 下载地址: <http://jdk.java.net/13/> 该版本功能包含了 [JSR 388][1] 中的 JavaSE 参考实现。 发布说明 JDK13 最新版本为 Build 17,包含了下列变更: - "Build 16: " - 在 `security-libs/javax.net.ssl` 中,更新加密套件的默认配置 (JDK-8163326)。 应用可自己选择加密套件并自定义配置 - "Build 15: " - 在 `core-libs/java.time` 中,增加日本新年号 Reiwa(令和)支持 (JDK-8205432) - 在 `core-libs` 中,新增 Reiwa(令和)支持 (JDK-8174268) - 在 `security-libs` 中,移除重复的 RSA 服务支持 (JDK-8220016)。 取消 SunJSSE provider 提供的 RSA KeyFactory、RSA KeyPairGenerator、MD2withRSA、MD5withRSA 和 SHA1withRSA

数组阻塞队列(ArrayBlockingQueue)源码解读与分析

*爱你&永不变心* 提交于 2021-01-15 13:15:24
生产者消费者模式最核心的部分是生产者与消费者之间的特殊容器,而阻塞队列是特殊容器最常见的实现。JDK中定义了阻塞队列接口BlockingQueue,JDK通过该接口为我们提供了很多种阻塞队列的实现,其中包括本节的主角ArrayBlockingQueue,该类位于java.util.concurrent.ArrayBlockingQueue.java。该类需要实现的核心方法如下,下面我们详细分析ArrayBlockingQueue的实现原理。 从名字可以看出它的存储结构就是一个数组,即基于数组实现了一个FIFO的阻塞队列。新元素都插入到队列尾部,于是最先进入的元素在队列头而最后进入的元素在队列尾部。该数组是有界的,所以构造时需要制定数组的大小。此外,该阻塞队列还提供公平和非公平两种模式。 使用例子 在分析 ArrayBlockingQueue的实现原理之前我们先通过几个例子来了解它的使用。例子一中我们创建了一个 ArrayBlockingQueue对象,然后通过五个线程去生产数据并put到阻塞队列,二主线程则充当消费端,不断将阻塞队列中的数据取出消费。程序输出如下: 主要展示了阻塞队列空间满了产生阻塞,我们创建一个最大长度为4的阻塞队列,然后通过五个线程分别产生一个数据put到阻塞队列中,但由于阻塞队列最大长度为4,所以在put四个数据后会产生阻塞。 主要展示了阻塞队列为空时产生阻塞

java之常用API

大兔子大兔子 提交于 2021-01-15 07:38:17
1 Scanner类 1.1 API的概述 API (Application Program Interface):应用程序接口;是Java提供很多类和接口以来帮助我们编程。我们在拿到一个API文档的时候,第一个要看包路径;第二看构造方法;第三看方法摘要。 1.2 引用类型的使用步骤 功能:可以实现键盘输入数据。 引用类型的一般使用步骤:( 除了基本数据类型,都是引用类型 ,所以scanner也是一个引用类型) (1 )导包 import 包路径.包名称; 特殊情况:在java的API中,只有 java.lang包下的内容不需要导包 ,可以直接使用;比如String类。 ( 2 )创建 类名称 对象名 = new 类名称(); ( 3 )使用 对象名.成员方法名(); 1.3 Scanner类的使用步骤 package com.yc.page4; import java.util.Scanner; // 1.导包 public class ScannerDemo { public static void main(String[] args) { Scanner sc = new Scanner(System.in); //2、创建 int num= sc.nextInt(); //3、使用 System.out.println( "输入的是"+num); // 输入数字

Java 常用API

五迷三道 提交于 2021-01-15 07:37:50
常用api第一部分 String 类 双引号字符串,都是 String 类的对象 字符串的特点: 字符串的内容永不可变(正是因为字符串不可改变,所以字符串是可以共享使用的) 字符串效果上相当于是 char[] 字符数组,但是底层原理是 byte[] 字节数组 字符串的常见的 3 + 1 种创建方式 public class DemoString { public static void main(String[] args) { // 最简单的方式创建一个字符串 String str = "johny" ; // 使用空参构建 String str1 = new String(); System.out.println(str1); // "" // 根据字符数组的内容,来创建对应的字符串 char [] charArray = {'A', 'B', 'C' }; String str2 = new String(charArray); System.out.println(str2); // "ABC" // 根据字节数组的内容,来创建对应的字符串 byte [] byteArray = {97, 98, 99 }; String str3 = new String(byteArray); System.out.println(str3); // "abc" } } 字符串常量池

深入JVM垃圾回收机制,值得你收藏

坚强是说给别人听的谎言 提交于 2021-01-15 06:12:54
JVM可以说是为了Java开发人员屏蔽了很多复杂性,让Java开发的变的更加简单,让开发人员更加关注业务而不必关心底层技术细节,这些复杂性包括内存管理,垃圾回收,跨平台等,今天我们主要看看JVM的垃圾回收机制是怎么运行的,希望能够帮到大家, 哪些对象是垃圾呢? Java程序运行过程中时刻都在产生很多对象,我们都知道这些对象实例是被存储在堆内存中,JVM的垃圾回收也主要是针对这部分内存,每个对象都有自己的生命周期,在这个对象不被使用时,这个对象将会变成垃圾对象被回收,内存被释放,那么如何判断这个对象不被使用呢?主要有如下两种方法: 引用计数算法 这个方法什么意思呢?就是给每个对象绑定一个计数器,每当指向该对象的引用增加时,计数器加1,相反减少时也会减1,当计数器的值变为0时,该对象就会变成垃圾对象,也就是最终没有任何引用指向该对象。这种方法比较简单,实现起来也容易,但有一个致命缺点,有可能会造成内存泄漏,也就是垃圾对象无法被回收,我们看下面代码,创建两个对象,每个对象的成员变量都持有对方的引用,这就是一个循环引用,形成了一个环,此时虽然两个对象都不再使用了,但每个对象的计数器并不为0,导致无法被回收,那有办法解决吗?当然有,看下面的算法。 class Person { public Object object = null; public void test(){ Person