
Java
文章平均质量分 82
timo_xin
codeing
展开
-
必知必会--Optional那点事
A container object which may or may not contain a non-null valueOptional作为JDK1.8引入的一个新特性,官方介绍Optional是一个判断对象是否为空的容器。虽然Optional的代码只有350行(还包括大量的注释),但是功能却不简单,算得上小巧而又精悍。在Optional出现之前我们是如何判断为空呢。if(null == object){...}相信这段代码大家再熟悉不过了。假设现在有一个需求,利用下面给出的jso原创 2021-07-25 19:47:13 · 526 阅读 · 0 评论 -
Java并发--ReentrantReadWriteLock饥饿问题
前言通过阅读ReentrantReadWriteLock的源码我们会发现ReentrantReadWriteLock内部通过AbstractQueuedSynchronizer来实现同步语义,在ReentrantReadWriteLock中拥有读锁与写锁。读锁是一种共享锁,允许多个线程同时获取锁,写锁是一种独占锁,同一时刻只允许一个线程获取。如果在读多写少的情况下,利用ReentrantReadWriteLock很容易造成饥饿问题。饥饿问题:ReentrantReadWriteLock实现了读写分离原创 2020-08-11 23:22:48 · 2195 阅读 · 4 评论 -
Java并发--ArrayBlockingQueue如何实现阻塞队列
前言ArrayBlockingQueue是一个由数组结构组成的有界阻塞队列。同时此队列按照先进先出的原则对元素进行排序。阻塞队列与普通的队列相比较,有两个特殊的操作。一是支持阻塞的插入方法,当队列满时,队列会阻塞插入元素的线程,直到队列不是满时。二是支持阻塞的移除元素,当队列为空时,队列会阻塞移除元素的线程,直到队列非空。那ArrayBlockingQueue如何实现这两个特殊的阻塞操作。正文ArrayBlockingQueue中利用通知模式来实现阻塞语义。所谓通知模式,假设向队列中插入元素的线原创 2020-07-22 14:30:22 · 426 阅读 · 0 评论 -
Java并发--ReentrantReadWriteLock如何管理读写锁
前言读写锁ReentrantReadWriteLock管理了一组锁,一个读锁,一个写锁。当写锁被获取到时,后续(非当前写操作线程)的读写操作都会被阻塞,写锁释放后,所有的操作继续执行。而当读锁被获取时,后续的任意线程的读锁都可被获取,写锁会被阻塞,当读锁被完全释放后,线程可以获取到写锁。可以看出读锁是共享式锁,写锁是独占式锁。那在ReentrantReadWriteLock中如何管理读写锁?读锁与写锁的获取释放过程是什么?正文ReentrantReadWriteLock中读写锁分别对应着Read原创 2020-06-23 16:09:35 · 267 阅读 · 0 评论 -
Java并发--重入锁ReentrantLock公平性与非公平性的区别
前言重入锁ReentrantLock有两种方式获取锁,一种是公平性,一种是非公平性。如果在绝对时间上,先请求获取锁的线程一定会先获取到锁,那么这个锁就是公平的,反之,这个锁就是不公平的。公平的获取锁,也就是等待时间最长的线程最优先获取锁,也可以说锁获取是顺序的。那重入锁ReentrantLock如何实现公平锁,以及非公平锁,它们的区别又是什么?正文重入锁ReentrantLock默认使用非公平获取锁,同时提供构造函数,能够控制锁是否是公平。 public ReentrantLock(原创 2020-06-22 17:38:42 · 267 阅读 · 0 评论 -
Java并发--重入锁ReentrantLock如何实现重入性
前言重入锁ReentrantLock,就是支持线程重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁。synchronized关键字隐士的支持锁的可重入性。利用synchronized,执行线程在获取锁之后仍然可以多次获取锁。而ReentrantLock是通过显示去完成锁的可重入性,接下来我们探讨ReentrantLock如何实现可重入性。正文重入性是指任意现场在获取到锁之后再次获取该锁而不会被锁阻塞,重入性的实现主要需要解决两个问题。线程再次获取锁。锁需要去识别获取锁的线程是否为当前占原创 2020-06-22 16:07:40 · 1227 阅读 · 0 评论 -
Java并发--队列同步器AbstractQueuedSynchronizer
前言在Java的多线程环境,如果需要控制多个线程访问共享资源时,我们可以使用synchronized来提供同步,实现锁功能。在Java SE 5之后,Java并发包新增了Lock接口以及相关实现类,我们可以使用Lock实现与synchronized相同的锁功能。由于Lock锁在使用时需要显式地区获取和释放锁,使锁的释放和获取具有可操作性,也衍生了一些功能各异的锁。例如可重入锁ReentrantLock,可重入读写锁ReentrantReadWriteLock。当我们去分析ReentrantLock,Re原创 2020-06-22 10:51:00 · 248 阅读 · 0 评论 -
手机靓号AABB,ABAA,AABB等规则的正则表达式
正文将11位的手机号进行靓号标识,前7位不做特殊判断,后四位进行靓号判断,同时AAAA不允许满足AABB,AAAB,ABAB等情况。1.尾号AABB:^[0-9]{7}(\d)\1((?!\1)\d)\2$2.尾号AAA:^[0-9]{8}(\d)(\d)\1$3.尾号AAAB:^[0-9]{7}(\d)(\d)\1((?!\1)\d)$4.尾号ABAB:^[0-9]{7}(\d)((?!\1)\d)\1\2$5.尾号AABA:^[0-9]{7}(\d)\1((?原创 2020-06-15 20:58:59 · 21920 阅读 · 0 评论 -
错误排查:Cannot get a connection, pool error Timeout waiting for idle object
前言项目需要将某一表中的数据同步到搜索中,在进行数据同步时报错提示,Cannot get a connection, pool error Timeout waiting for idle object。报错提示很容易理解,无法获取连接,连接池等待空闲连接超时。排查过程1:查看数据库连接池设置的参数max-active: 20initial-size: 1min-idle: 3max-wait: 600这是我数据库连接池的参数,当你发现连接数设置的国小,可以适当调大相关参数。我在原创 2020-05-21 21:06:18 · 6310 阅读 · 0 评论 -
Java线程执行native方法时程序计数器为空,如何确保native执行完后的程序执行的位置
絮叨今天在看深入理解Java虚拟机这本书的时候,里面有这句话,如果正在执行的是Native方法,这个计数器值为空(Ubdifined)。看完之后有一点不理解,native方法执行时,程序计数器为空,那执行后,怎么确保接下来执行的位置?这个问题查看了一些资料,在这里参考R大的回答做一个小总结。R大的回答:https://www.zhihu.com/question/40598119/an...原创 2019-12-18 11:38:16 · 2383 阅读 · 0 评论 -
必知必会--HashMap容量细节
絮叨HashMap作为Java中最常用的数据结构之一,在工作中使用HashMap的频率和你遇见NullPointException一样多,在面试中被问到的概率和问你名字的概率一样大。既然工作,面试经常遇到,我们有必要熟悉HashMap的每一个细节。作为最常用的数据结构之一,我们都知道HashMap的容量为2次幂。当被问到为什么是2次幂时,大家应该都能回答出来,是为了均匀分散到数组中。但是2次幂...原创 2019-12-13 19:43:11 · 624 阅读 · 3 评论 -
必知必会--ConcurrentHashMap锁分段原理
前言HashMap是线程不安全的类,JDK1.8之前多线程的情况下,如果多次put操作会导致死循环,尽管JDK1.8对HashMap进行了优化,但是HashMap并不是为了线程安全而设计的类,因此多线程下我们应该尽量避免使用HashMap。Hashtable是线程安全的类,但是当Hashtable进行put操作时会将整个Hashtable对象锁起来,只允许一个线程向Hashtable中pu...原创 2019-10-12 12:21:31 · 3147 阅读 · 1 评论 -
必知必会--Hashtable扩容机制
前言今天阅读源码时,在Hashtable的扩容机制看到一个有意思的点,整理之后写出来分享给大家。正文Hashtable的扩容机制通过rehash()来实现,如果Hashtable中元素的个数大于临界值时,会调用rehash()来实现扩容。临界值的大小等于Hashtable数组的大小与负载因子相乘,默认的负载因子大小为0.75。protected void rehash() { ...原创 2019-09-16 14:54:32 · 11294 阅读 · 0 评论 -
必知必会--HashMap扩容机制
前言JDK1.8对HashMap进行的较大的改动,其中对HashMap的扩容机制进行了优化。在JDK1.8前,在多线程的情况下,使用HashMap进行put操作会造成死循环。这是因为多次put操作会引发HashMap的扩容机制,HashMap的扩容机制采用头插法的方式移动元素,这样会造成链表闭环,形成死循环。JDK1.8中HashMap使用高低位来平移元素,这样保证效率的同时避免了多线程情...原创 2019-09-11 14:59:42 · 4322 阅读 · 5 评论