本文接着对java.lang.String进行总结学习。

String 类是日常开发中使用最频繁的类之一,同时也是非常重要的一个类。

String表示字符串,Java中所有字符串的字面值都是String类的实例,例如“ABC”。字符串是常量,在定义之后不能被改变,字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享它们。

Read More

什么是CyclicBarrier

CyclicBarrier是一个同步工具类,它允许一组线程互相等待,直到到达某个公共屏障点。与CountDownLatch不同的是该barrier在释放等待线程后可以重用,所以称它为循环(Cyclic)的屏障(Barrier)。

CyclicBarrier大致是可循环利用的屏障,顾名思义,这个名字也将这个类的特点给明确地表示出来了。首先,便是可重复利用,说明该类创建的对象可以复用;其次,屏障则体现了该类的原理:每个线程执行时,都会碰到一个屏障,直到所有线程执行结束,然后屏障便会打开,使所有线程继续往下执行。

CyclicBarrier支持一个可选的Runnable命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作很有用。

Read More

我们在Java并发下常常使用synchronized进行线程同步操作。synchronized的语义是互斥锁,就是在同一时刻,只有一个线程能获得执行代码的锁。但是现实生活中,有好多的场景,锁不止一把。

由于synchronized是悲观锁,同一时刻只能有一个线程处于运行状态。对于同一时刻要有n个线程同时工作这种需求,用synchronized显然不合适。

查看Java并发工具,发现有一个Semaphore类,天生就是处理这种情况的。

什么是Semaphore

Semaphore是一种基于计数的信号量。它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做完自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞。Semaphore可以用来构建一些对象池,资源池之类的,比如数据库连接池,我们也可以创建计数为1的Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量,表示两种互斥状态。

Read More

从本文开始我们对Java并发包中的AQS相关类进行学习及总结,首先了解的是java.util.concurrent.CountDownLatch类。

AQS,即AbstractQueuedSynchronized,中文翻译为抽象队列式同步器。它定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch…。

本文先不展开讲解AQS,它值得用一篇完整的文章来总结。

Read More

我们在打包的时候有个需求是要动态的更新application.properties中的一个配置属性值,如:

application.version=@project.version@

这里将属性的value配置为环境变量,目标为pom.xml中设置的版本号,这样我们就能在执行mvn package时自动将变量替换为真实值,保证我们在代码中能够实时获取到应用的版本号的变更,并且不需要每次打包都手动更改属性值,避免了有时候明明要更改却忘记更改的问题。

Read More

看到好些人在写更新缓存数据代码时,先删除缓存,然后再更新数据库,而后续的操作会把数据再装载的缓存中。

然而,这个是逻辑是错误的。试想,两个并发操作,一个是更新操作,另一个是查询操作,更新操作删除缓存后,查询操作没有命中缓存,先把老数据读出来后放到缓存中,然后更新操作更新了数据库。于是,在缓存中的数据还是老的数据,导致缓存中的数据是脏的,而且还一直这样脏下去了。

我不知道为什么这么多人用的都是这个逻辑,当我在微博上发了这个贴以后,我发现好些人给了好多非常复杂和诡异的方案,所以,我想写这篇文章说一下几个缓存更新的Design Pattern(让我们多一些套路吧)。

Read More

使用springboot开发应用已经有一段时间了,我们都沉醉于它简洁的配置和平滑的上手曲线。

在springboot的开发中,starter是一个核心的配置,只需要引入对应模块的starter,然后在application.properties中引入对应的配置项,就可以开发业务逻辑了。

这一切都归功于springboot的自动配置的能力。

那么本文就让我们基于Jedis客户端封装一个我们自己的简易版starter,较为深入的了解一下springboot的自动配置魔法。

Read More

在分布式系统的很多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务、分布式锁等。

有的时候,我们需要保证一个方法在同一时间内只能被同一个线程执行。在单机环境中,Java中其实提供了很多并发处理相关的API,但是这些API在分布式场景中就无能为力了。也就是说单纯的Java Api并不能提供分布式锁的能力。

目前针对分布式锁的实现目前有多种方案:

基于数据库实现分布式锁
基于缓存(redis,memcached)实现分布式锁
基于Zookeeper实现分布式锁

在分析这几种实现方案之前我们先来想一下,我们需要的分布式锁应该是怎么样的?(这里以方法锁为例,资源锁同理)

可以保证在分布式部署的应用集群中,同一个方法在同一时间只能被一台机器上的一个线程执行。

这把锁要是一把可重入锁(避免死锁)
这把锁最好是一把阻塞锁(根据业务需求考虑要不要这条)
有高可用的获取锁和释放锁功能
获取锁和释放锁的性能要好

Read More

从本文开始讲陆续对JDK关键源码进行解析和总结。先从Java最为核心的类Object入手。

1.总述

java.lang.Object,是Java所有类的父类,当你在编写一个Java类的时候没有显式的指定extends一个父类,编译器会默认的添加Object为该类的父类。

如果类A有指定父类,那么一直往上追溯,一定能找到最顶层的类没有指定父类,那么,最顶层的类就是Object。

Read More

Fork me on GitHub