Java基础
库昊天
这个作者很懒,什么都没留下…
展开
-
Java基础之ConcurrentHashMap(二)
基于CAS的ConcurrentHashMap(JDK1.8)数据结构 JDK8版本的实现摒弃了JDK6版本中Segment(锁段)的概念,底层利用“数组”+链表+红黑树的方式实现了全并发。 构造函数 构造函数只是确定了数组的初始容量,并没有真正创建数组,第一次插入元素时才会创建数组。 public ConcurrentHashMap(int initi...原创 2018-03-20 19:19:30 · 277 阅读 · 0 评论 -
Java并发之ReentrantReadWriteLock
ReentrantReadWriteLock介绍可重入的读写锁,将读写分离,读共享,写互斥,适用于读多写少的场景,其特点如下: State复用 读写锁内部维护者两把锁,读锁和写锁。写锁需要一个变量表示写锁被重入的次数,读锁需要一个变量表示读锁被占用的次数。读写锁内部实现将state属性复用,将其切分为两部分,高16位表示读,低16位表示写,通过位运算得到读锁和写锁的状态。 stat原创 2018-04-04 10:40:30 · 133 阅读 · 0 评论 -
Java并发之线程池
线程池作用提高响应速度。通过线程复用,避免频繁创建和销毁线程的性能开销;限定线程资源使用上限,防止无限制创建线程,造成OOM;线程池工作原理 线程池的两个关键元素:线程数组和任务队列。线程池通过参数corePoolSize设置线程数量的下限,通过参数maximumPoolSize设置线程数量的上限,具体工作流程如下图所示: 线程池的参数配置线程数量的设置:对于CPU密集型任务应尽可能少的线原创 2018-04-05 11:07:17 · 152 阅读 · 0 评论 -
Java并发之原子类
以AtomicInteger为例进行说明。什么是原子类? JDK并发包下以Atomic开头的一组类,特点是提供的接口能保证原子性。实现原理 volatile变量+CAS缺点 高并发场景下CAS失败率升高,导致CPU飙升;改进方案 查看LongAdder,基本原理是增加辅助数组来分担压力;原创 2018-04-05 15:28:06 · 186 阅读 · 0 评论 -
Base64编码原理与应用
转载:https://www.tuicool.com/articles/JjYnUjq什么是Base64编码? Base64编码本质上是一种将二进制数据转成文本数据的方案,使用64个字符来对任意数据进行编码。Base64编码原理 对于非二进制数据,是先将其转换成二进制形式,然后每连续6比特(2的6次方=64)计算其十进制值,根据该值在索引表中找到对应的字符,最终得到一个文本字符串。 Base6转载 2018-04-18 14:40:36 · 311 阅读 · 0 评论 -
安全相关算法比较
对称加密算法 对称加密推荐使用AES算法,无论是加解密效率,还是安全性都有明显优势。 非对称加密算法 优先推荐ECC算法,但是JDK支持不是很好;其次,推荐使用密钥长度为2048的RSA算法,坚固安全性和效率。 哈希算法 哈希算法推荐使用SHA256算法,兼顾效率和安全性,MD5和SHA1不推荐使用。原创 2018-04-18 16:19:42 · 433 阅读 · 0 评论 -
HMAC算法
HMAC算法 HMAC(Hash Message Authentication Code),中文名“散列消息鉴别码”,主要是利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。 HMAC算法作用数据完整性校验;身份认证;HMAC VS HASH HMAC基于HASH,但是与HASH相比,又多了密钥,因此安全性上要比相同的HASH要高。HMAC VS MAC MAC算法相原创 2018-04-18 20:37:10 · 5584 阅读 · 0 评论 -
跨语言通信方案比较
转载:https://kaimingwan.com/post/fen-bu-shi/kua-yu-yan-tong-xin-fang-an-bi-jiao-thrift-protobufhe-avro传统方案基于SOAP消息格式的WebService优点:可读性好、数据描述性好;缺点:XML体积太大,解析性能极差;基于JSON消息格式的RestFul服务优点:JSON体积相对较小,解析相对较转载 2018-05-03 10:16:10 · 915 阅读 · 0 评论 -
引用Reference
引用相关类引用分类强引用 特点:只要有强引用存在,对象不会被GC,即使出现OOM;软引用(SoftReference) 特点:当内存不足时,被软引用指向的对象会被GC。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。弱引用(WeakRe...原创 2018-04-28 10:40:08 · 182 阅读 · 0 评论 -
Java并发之CopyOnWriteArrayList
特点 线程安全的ArrayList原理 读不加锁,写加锁,写时生成新的数组,数据拷贝。get() 直接读取,无加锁操作,如代码所示: @SuppressWarnings("unchecked") private E get(Object[] a, int index) { return (E) a[index]; } /**...原创 2018-05-14 12:00:12 · 140 阅读 · 0 评论 -
Java并发之双重检查锁DCL ☆☆☆☆☆
问题分析问题:多线程情况下可能得到未被初始化的Singleton对象; 原因: synchronized代码块中的语句可能发生重排序;public class Singleton { private static Singleton singleton; private Singleton(){} public static Singleton getInstance(){原创 2018-03-28 19:13:13 · 471 阅读 · 0 评论 -
Java并发之synchronized
synchronized介绍 synchronized是JVM内置的锁,其特点是具有互斥性,可作用在方法和代码块上,本质是对象锁。以方法块为例进行说明,java文件被编译成class文件时,方法前后分别被插入monitorenter和monitorexit指令。当执行到monitorenter指令时,在对象头查看锁的状态,如果对象没有被加锁或者已经被当前对象占用,则计数器加1;如果被其它线程...原创 2018-03-28 11:55:00 · 175 阅读 · 0 评论 -
Java并发之volatile
volatile的作用可见性。当一个线程修改了被volatile修饰的变量后,无论是否加锁,其它线程都可以立即看到最新的修改。有序性。程序按照代码的先后顺序执行。volatile的实现原理可见性实现原理修改volatile变量时会强制将修改后的值刷新的主内存中;同时将其它线程工作内存中对应的变量值失效;有序性实现原理 JVM使用“内存屏障”来实现volatile语义。内存屏障,也叫做内原创 2018-03-27 20:21:27 · 353 阅读 · 1 评论 -
Java基础之ThreadLocalRandom
Random缺陷 Random虽然是线程安全的,但是在多线程下效率比较低,而且Random产生的随机数可能被预测,顾不适合做验证码类的随机数生产。ThreadLocalRandom 相当于每个线程拥有一个Random实例,彻底杜绝了线程间的竞争,因此多线程情况下性能表现良好。参考:http://ifeve.com/%E5%B9%B6%E5%8F%91%E5%8C%85%E4%B8%ADthrea原创 2018-03-20 20:56:13 · 242 阅读 · 0 评论 -
Java并发之AQS
AQS介绍 AQS(AbstractQueuedSynchronizer),是JDK并发包下的锁模板,包含共享模式和排他模式,是并发包下大部分的基础,如ReentrantLock、Semaphore和CountDownLatch等等。State属性和CLH队列是AQS的关键元素,子类通过State属性判断线程是否需要阻塞,CLH队列为线程阻塞队列,提供了线程阻塞和唤醒的实现。AQS原理概...原创 2018-03-25 14:46:13 · 408 阅读 · 0 评论 -
Java基础之LongAdder
数据结构 实际的计数结果由base和Cell数组两部分组成,当需要读取结果时只需要将base和Cell的value累加即可。 public long sum() { Cell[] as = cells; Cell a; long sum = base; if (as != null) { for (in...原创 2018-03-21 17:40:11 · 499 阅读 · 0 评论 -
Java对象内存布局
转载:http://www.ideabuffer.cn/2017/05/06/Java%E5%AF%B9%E8%B1%A1%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80/ 我们知道在Java中基本数据类型的大小,例如int类型占4个字节、long类型占8个字节,那么Integer对象和Long对象会占用多少内存呢?本文介绍一下Java对象在堆中的内存结构以及对象大小的计算转载 2018-03-21 19:17:47 · 244 阅读 · 0 评论 -
理解CPU Cache
转载:http://www.ideabuffer.cn/2017/05/07/%E7%90%86%E8%A7%A3CPU-Cache/CPU Cache介绍 随着CPU频率的不断提升,内存的访问速度却并没有什么突破。所以,为了弥补内存访问速度慢的硬伤,便出现了CPU缓存。它的工作原理如下:当CPU要读取一个数据时,首先从缓存中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就用相对慢的转载 2018-03-21 19:26:38 · 693 阅读 · 0 评论 -
Java并发之CAS
什么是CAS? CAS(Compare and Swap)比较并交换,一种乐观锁机制,是CPU级别的指令,能够保证操作的原子性,是Java并发包的基础。JDK在sun.misc包下Unsafe的类里提供了CAS相关的方法。CAS实现原理 基于cmpxchg汇编指令实现。CAS优缺点优点高效:硬件级别的原子操作,性能高;保证操作的原子性;缺点不适用...原创 2018-03-31 12:29:18 · 328 阅读 · 0 评论 -
Java8使用@sun.misc.Contended避免伪共享
转载:http://www.ideabuffer.cn/2017/05/12/Java8%E4%BD%BF%E7%94%A8-sun-misc-Contended%E9%81%BF%E5%85%8D%E4%BC%AA%E5%85%B1%E4%BA%AB/什么是伪共享? 缓存系统中是以缓存行(cache line)为单位存储的。缓存行是2的整数幂个连续字节,一般为32-256个字节。最常见的缓存行大转载 2018-03-21 20:30:28 · 503 阅读 · 0 评论 -
Java基础之数组内存分配
数组名即引用在Java栈空间,数组元素在堆,并且空间连续。正式因为内存地址空间连续,访问数组元素时只需要根据起始地址和元素偏移量即可快速访问数组中的任意元素。如果数组元素是基本类型,数组存放的是基本类型的值,空间中是连续存放的;如果数组元素是引用类型,数组存放的是对象的引用,数组元素是连续存放的,但引用的对象则不一定了。原创 2018-03-27 10:10:40 · 387 阅读 · 0 评论 -
Java并发之基础理论
线程不安全分析 对共享变量进行写操作时,原子性、可见性和有序性不能同时保障,导致线程不安全,如下图所示: 反过来说,如果没有共享变量,或者只存在共享变量的读操作则不会存在线程安全问题。原子性定义:原子性就是指对数据的操作是一个独立的、不可分割的整体。也就是说线程A操作数据的过程中,其它线程是无法进行修改的。 非原子性原因:一条操作系统指令的执行是原子性的,但是通常Jav...原创 2018-03-27 11:34:42 · 242 阅读 · 0 评论 -
JDK异常类
类体系Throwable:所有异常类的基类,有两个重要的子类Exception(异常)和 Error(错误);Error:JVM内部抛出的错误,是程序无法处理的错误;Exception:程序内部抛出的异常,是程序本身可以处理的异常;Checked Exception VS UnChecked Exception不可查异常,是指运行期间不可预知的异常,包括运行时异常(R...原创 2018-05-15 17:50:42 · 2187 阅读 · 0 评论 -
怎么实现所有线程在等待某个事件的发生才会去执行?
方案一:读写锁 刚开始主线程先获取写锁,然后所有子线程获取读锁,然后等事件发生时主线程释放写锁;方案二:CountDownLatch CountDownLatch初始值设为1,所有子线程调用await方法等待,等事件发生时调用countDown方法计数减为0;方案三:Semaphore Semaphore初始值设为N,刚开始主线程先调用acquire(N)申请N个信号量,...原创 2018-05-16 16:31:54 · 2506 阅读 · 1 评论 -
LockSupport工具
作用park*:阻塞当前线程;unpark:唤醒被阻塞的线程;blocker作用 丰富Dump的堆栈信息,方便问题排查,如下图所示: 原理待补充。。。转载:https://www.jianshu.com/p/ceb8870ef2c5...转载 2018-05-16 17:23:34 · 230 阅读 · 0 评论 -
Java正则使用注意
通配符’.’ 默认情况下,’.‘不匹配换行符,需要指定Pattern.DOTALL,让’.'匹配包括换行在内的所有单个字符,如下示例:Pattern.LITERAL Pattern.LITERAL:平白字符模式,所有元字符、转义字符都被看成普通的字符,如下示例:大小写不敏感 Pattern.CASE_INSENSITIVE:正则不再对数据的大小写敏感,如下示例。当然也可以通过正则匹配...原创 2019-01-11 10:30:35 · 260 阅读 · 0 评论 -
commons.pool2 对象池的使用
maven依赖<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.3</version></dependency&g原创 2019-01-06 15:20:32 · 1073 阅读 · 0 评论 -
hashCode() VS identityHashCode()
System.identityHashCode() 不管对象的hashCode()是否重写,总是返回对象物理地址的哈希值,即Object默认的hashCode()逻辑; /** * Returns the same hash code for the given object as * would be returned by the default method h...原创 2019-01-06 16:15:19 · 146 阅读 · 0 评论 -
JDK8 --- Optional
作用 避免Null检查,防止NullPointerException;传统做法 进行非Null检查和特殊处理,代码繁琐不够优雅,对比如下所示: // 传统做法User user = …..if (user != null) { return user.getOrders();} else { return Collections.emptyList();} //Op...原创 2019-01-25 16:01:49 · 213 阅读 · 0 评论 -
JDK8 --- Future异步编程
Future演变史JDK5正式提出Future特性支持异步编程,但只能算是半异步,因为需要通过阻塞或轮询的方式获取结果;Netty/Guava等众多三方库对Future功能进行增强,提供注册回调函数、主动完成等功能;JDK8借鉴各家所长,正式推出了官方版的CompletableFuture,自此Java有了内置的异步编程模型;参考:Guava ListenableFuture到 ...原创 2019-01-23 14:35:10 · 787 阅读 · 0 评论 -
JDK8 --- Stream
Stream处理过程流的创建由值创建: Stream.of();由数组创建: Arrays.stream();由集合创建: Collection.stream();由文件创建: Files.lines();由函数创建: iterate()和generate();中间处理函数 一个流后面可以跟零个或多个中间函数,也就是说中间处理函数的输入为一个流,经过处理后,输出为另一...原创 2019-01-30 11:11:34 · 205 阅读 · 0 评论 -
JDK8 ---方法引用
方法引用语法{类名\实例对象}::{方法名}几种使用方式构造函数引用{类名}::new静态方法引用{类名}::{方法名}特定类的任意对象的方法引用{类名}::{方法名}特定对象的方法引用{实例对象}::{方法名}参考:http://www.runoob.com/java/java8-method-references.html...原创 2019-01-30 11:52:00 · 249 阅读 · 0 评论 -
HashMap注意点
注意点1:初始容量设置 尽量根据业务场景设置合理的初始容量(2的幂次方),避免频繁扩容和数据迁移,以此提升性能;注意点2:默认最大容量表容量/桶个数最大为2^30(MAXIMUM_CAPACITY设定),当桶个数超过设定上限时不再扩容;元素个数没有上限,当不断地往map中添加元素时,要么由于内存不够导致OOM,要么桶个数达到上限碰撞概率变大,导致map性能变差,实际生产中往往需要设定m...原创 2019-05-22 20:56:36 · 581 阅读 · 0 评论 -
新一代Java缓存库 Caffeine
基本介绍 Caffeine是新一代Java缓存库,相比于Google的Guava Cache和ConcurrentLinkedHashMap性能更加出色,主要原因是采用了Window TinyLfu回收策略,比LRU提供了更高的缓存命中率,官网性能如下:使用说明pom依赖<dependency> <groupId>com.github.ben-manes...原创 2019-06-01 10:18:04 · 693 阅读 · 0 评论 -
获取本地IP工具类
方式一:InetAddress工具类public static String getLocalIP() { try { return InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException e) { throw new RuntimeException(e...原创 2018-12-26 22:54:40 · 277 阅读 · 0 评论 -
返回空List的方式
方式一:new ArrayList() JDK1.8已经优化了,默认构造函数创建的list内部共享空数组,首次插入数据时才会扩容到默认容量;private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};public ArrayList() { this.elementData = DEFAULTCAP...原创 2018-11-27 21:12:56 · 19459 阅读 · 0 评论 -
输入流的合并---SequenceInputStream
整体思路:将多个输入流InputStream在逻辑上拼接成一个大的输入流,依次读取每个流,如下图所示;关键代码分析初始化时,设置要合并的输入流集合e和当前要读取的输入流in;读取数据时,如果当前流结束,则读取下个输入流;public SequenceInputStream(Enumeration<? extends InputStream> e) { ...原创 2018-11-13 13:31:08 · 1663 阅读 · 0 评论 -
jar打包命令使用
语法用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files … 选项:-c 创建新档案;-t 列出档案目录;-x 从档案中提取指定的 (或所有) 文件;-u 更新现有档案;-v 在标准输出中生成详细输出;-f 指定档案文件名;-m 包含指定清单文件中的清...原创 2018-06-21 10:54:01 · 1146 阅读 · 0 评论 -
URL协议处理器Handler
URL组成 URL格式: protocol://[authority]hostname:port/resource?queryString 说明:每种协议对应一种特定handler进行解析处理,JDK内置了HTTP 、 File 、 FTP和Jar等协议的。Handler 作用:每个Handler解析一种特定的协议,获取资源; 命名规范: Handler类的命名模式为...原创 2018-06-21 14:04:47 · 2447 阅读 · 3 评论 -
Jar包资源文件的加载
加载方式 如下图所示,通过通过类加载器 ClassLoader的getResource或者getResourceAsStream方法获取资源文件。 存在问题 问题:无法加载嵌套Jar包中的资源。举例,A.jar中包含一个资源文件B.jar,同时B.jar中资源文件C.jpg,如果想加载C.jpg则不支持。解决方案 扩展URL的Jar协议及定制ClassLoader,具体...原创 2018-06-21 15:39:54 · 386 阅读 · 0 评论