关于Java锁细节的博客,蛮受读者欢迎的。也有许多不足,好比排版,一些细节等。Java锁细节与锁之编程细节讲述锁的两个不一样方面,因此分开写。Java锁细节是讲述每种锁的细节,把锁当作人的话,讲述的是男人,女人,大人,小孩的细节。锁之编程细节讲述的如高性能的使用锁。如同让人怎么跑得块而已。java
编程细节以下:算法
关于锁粗化与锁细化,在不少关于java优化的书籍都会讲解。好比java并发编程(是老胡并发与锁的启蒙书)等等。一些读者在读Java锁细节说没有讲解锁粗化。在你们的要求,老胡只能厚着面皮写下本博客了。编程
你们是否以为十分绕口,锁粗化,锁细化在名词上是两个对立的。为何都是优化的方法了?其实能够想象成长跑,短跑。就行了。api
receiveIntegerNoLock 方法调用了两个声明synchronized的方法。数组
public IntegeralInfo receiveIntegerNoLock(Integer addIntegeral) { addIntegeral(addIntegeral); addReceiveNum(); return this; } /** * 增长积分 * * @param addIntegeral */ public synchronized void addIntegeral(Integer addIntegeral) { this.integeralValue += addIntegeral; } /** * 增长签到次数 */ public synchronized void addReceiveNum() { this.receiveNum++; }
新的receiveInteger方法声明了synchronized。值使用了一个锁安全
public synchronized IntegeralInfo receiveInteger(Integer addIntegeral) { this.integeralValue += addIntegeral; this.receiveNum++; return this; }
需求,经过连续签到的天数,计算当次签到应获得多少积分,把计算出的积分增长到用户积分上,并计算除等级。并发
分析以下高并发
public synchronized void continuityReceiveIntegeralAlsoGradeSynchronized(Integer continuityDate) { // 经过天数计算,应该得到多少积分 int addIntegeral = calculationSignIntegeral(continuityDate); // 添加积分 this.integeralValue += addIntegeral; // 计算等级 gradeCalculation(); } public int calculationSignIntegeral(Integer continuityDate) { return continuityDate/1; } /** * 等级计算 */ private void gradeCalculation() { }
最简单的实现,没有进行任何的优化。三个操做的代码放到一个方法里面。观察calculationSignIntegeral方法会发现,只是进行数据计算,是一个安全的方法,能够不用上锁。gradeCalculation方法在必定程度上也是安全的方法,未实现。这个需求有点复杂,不知道那个大神,能够分析出来,并实现。性能
public void continuityReceiveIntegeralAlsoGrade(Integer continuityDate) { // 经过天数计算,应该得到多少积分 int addIntegeral = calculationSignIntegeral(continuityDate); // 添加积分 synchronized (this) { this.integeralValue += addIntegeral; } // 计算等级 gradeCalculation(); }
只对须要上锁的计算出的积分增长到用户积分上操做进行上锁,减小的上锁范围。缩短持有锁的时间,从而提升并发性能学习
java api里面的类,个个都写得十分优秀。是学习,深刻,理解基础技术的优质的代码。解读java.util.Hashtable的源码,从而理解public都是线程安全,而非public方法都是线程不安全的。当你看完java.util.Hashtable源码会发现,全部的public都是线程安全,而非public方法都是线程不安全的。
public都是线程安全,而非public方法都是线程不安全的。这种设计有一下特性
开闭原则(OCP)是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它不少的设计原则都是实现开闭原则的一种手段。对于扩展是开放的,对于修改是关闭的,这意味着模块的行为是能够扩展的
按照算法计算出的结果或者数据特性进行分类,分类中的每一个类型都有一把锁。能够减小锁争夺,更高并行度。
关于分段锁最简单的实现仍是在java api中,jdk6的ConcurrentHashMap。 ConcurrentHashMap经过hash算法获得key的hash值,在与数组长度求余,余数是数组下标。下标就是分类的类型 下面连接是一个大神写的关于jdk6的ConcurrentHashMap源码解读,写得有点乱,可是解读得十分详细。请点击
public class LockUser { static class IntegeralInfo { // 用户积分 private Integer integeralValue; // 经验值 private Integer experienceValue; // 签到 private Integer receiveNum; // 等级 private Integer grade; /** * 添加积分,同时增长签到次数 * * @param addIntegeral * 须要添加的积分 * @return */ public synchronized IntegeralInfo receiveInteger(Integer addIntegeral) { this.integeralValue += addIntegeral; this.receiveNum++; return this; } public IntegeralInfo receiveIntegerNoLock(Integer addIntegeral) { addIntegeral(addIntegeral); addReceiveNum(); return this; } /** * 增长积分 * * @param addIntegeral */ public synchronized void addIntegeral(Integer addIntegeral) { this.integeralValue += addIntegeral; } /** * 增长签到次数 */ public synchronized void addReceiveNum() { this.receiveNum++; } public synchronized void continuityReceiveIntegeralAlsoGradeSynchronized(Integer continuityDate) { // 经过天数计算,应该得到多少积分 int addIntegeral = calculationSignIntegeral(continuityDate); // 添加积分 this.integeralValue += addIntegeral; // 计算等级 gradeCalculation(); } public void continuityReceiveIntegeralAlsoGrade(Integer continuityDate) { // 经过天数计算,应该得到多少积分 int addIntegeral = calculationSignIntegeral(continuityDate); // 添加积分 synchronized (this) { this.integeralValue += addIntegeral; } // 计算等级 gradeCalculation(); } public int calculationSignIntegeral(Integer continuityDate) { return 1; } /** * 等级计算 */ private void gradeCalculation() { } } }