修饰静态方法默认获取当前class的锁,同步方法没有释放的锁,不影响class其他非同步方法的调用,也不影响不同锁的同步方法,更不影响使用class的其他属性.

package thread.base.sync;

import java.util.concurrent.TimeUnit;

/**
*
* @author ZhenWeiLai
*
*/
public class A { synchronized public static void saySomething() throws InterruptedException{
//前后可以写非同步代码
synchronized(A.class){
System.out.println("a");
TimeUnit.SECONDS.sleep(5);
}
//前后可以写非同步代码
} // /**
// * 与上面相等(但是方法内没有非同步区域):可以这么理解,把synchronized当修饰符用总不能写成synchronized(A.claa) public static void saySomething()
// * 这是静态方法啊,不需要实例就可以调用,那么我获取什么锁啊?只能获取本class的锁吖,你又不能给我传参
// */
// synchronized public static void saySomething() throws InterruptedException{
// System.out.println("a");
// TimeUnit.SECONDS.sleep(5);
// }
}

修饰非静态方法,默认获取调用此方法的实例对象锁    Spring容器管理的bean默认都是单例的(当然可以注解为prototype),所以加上 synchronized 的方法,注解自动装配获取的实例,调用都会同步了

package thread.base.sync;

import java.util.concurrent.TimeUnit;

/**
*
* @author ZhenWeiLai
*
*/
public class A { public void saySomething() throws InterruptedException {
//前面可以写非同步代码
synchronized (this) {
System.out.println("a");
TimeUnit.SECONDS.sleep(5);
}
//后面可以写非同步代码
} // /**
// * 与上面相等,看了静态的,再看对象方法更好理解.
// * 必须要有实例才能调用吧?太好办了那么我就获取当前实例对象的锁
// */
// synchronized public void saySomething() throws InterruptedException{
// System.out.println("a");
// TimeUnit.SECONDS.sleep(5);
// }
}

synchronized (object)与synchronized (this)一样,获取实例对象的锁.因为synchronized (this)只能获取当前实例锁,那么synchronized (object)就是可以获取其他实例锁的意思

对于synchronized 最简单粗暴的理解就是,你要哪些线程方法同步,就跟他们获取一样的锁好了,A.class,就获取A.class,  objectA 就获取 objectA(我说的不是对象名相同,而是真真切切在java堆中的同一个对象),

据说ConcurrentHashMap 就是用16个对象锁实现的

我也模拟一下

package thread.base.sync.hashmap;

import java.util.HashMap;
import java.util.concurrent.TimeUnit; /**
*
* @author ZhenWeiLai 模拟16个并发的线程安全put
* @param <K>
* @param <V>
*/
public class SyncHashMap<K, V> extends HashMap<K, V> {
/**
*
*/
private static final long serialVersionUID = 4071859310703431745L; // 初始化16个对象锁
Object[] lock = new Object[16]; public SyncHashMap() {
for (int i = 0; i < 16; i++) {
lock[i] = new Object();
}
} /**
* 线程安全方法
*
* @param key
* @param value
* @return
* @throws InterruptedException
*/
public V safePut(K key, V value) throws InterruptedException {
/**
* 不一样的key有可能得到一样的余数,据说hashcode算法问题.我这里是取巧,不深究
* 万一两个不同的key得到一样的余数,那么慢的一个就要等待5秒咯
* 随机获取16个对象锁中的一个
*/
synchronized (lock[key.hashCode() % 16]) {
System.out.println("aaaa");
TimeUnit.SECONDS.sleep(5);
// 同步调用原生put方法
return super.put(key, value);
}
} }

测试方法,两个key相同,其中获取锁慢的那个线程会等5秒再输出控制台

package thread.base.sync.hashmap;

/**
*
* @author ZhenWeiLai
*
*/
public class TestClass {
public static void main(String[] args) {
SyncHashMap<Integer,Integer> shm = new SyncHashMap<>();
new Thread(()->{
try {
//两个线程操作同一个key,
shm.safePut(1, 1);
} catch (Exception e) {
e.printStackTrace();
}
}).start(); new Thread(()->{
try {
//两个线程操作同一个key
shm.safePut(1,1);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}

试着简单易懂记录synchronized this object Class的区别,模拟ConcurrentHashMap的更多相关文章

  1. HashSet的实现原理,简单易懂

    HashSet的实现原理,简单易懂   答: HashSet实际上是一个HashMap实例,都是一个存放链表的数组.它不保证存储元素的迭代顺序:此类允许使用null元素.HashSet中不允许有重复元 ...

  2. 如果简单的记录,就可以为这个世界创造更多的财富,那么还有什么理由不去写博客呢? — 读<<黑客与画家>> 有感

    上一次博文发文时间是2016.1.15,7个月已经过去了.最近读了一本<>的书,对我触动挺大的!里面有关于技术趋势的探讨,也有关于人生和财富的思考! 开始更新iOS122的文章的初衷是,聚 ...

  3. Python简单爬虫记录

    为了避免自己忘了Python的爬虫相关知识和流程,下面简单的记录一下爬虫的基本要求和编程问题!! 简单了解了一下,爬虫的方法很多,我简单的使用了已经做好的库requests来获取网页信息和Beauti ...

  4. redis5.0.3单实例简单安装记录

    redis5.0.3单实例简单安装记录 日常需要测试使用,索性记录下来,免得临时又麻烦的找资料. yum -y install make gcc-c++ cmake bison-devel ncurs ...

  5. 【repost】让你一句话理解闭包(简单易懂)

    接触javascript很久了,每次理解闭包都似是而非,最近在找Web前端的工作,所以需要把基础夯实一下. 本文是参照了joy_lee的博客 闭包 在她这篇博客的基础上以批注的形式力争把我的理解阐述出 ...

  6. 5、Cocos2dx 3.0游戏开发找小三之測试例子简单介绍及小结

    重开发人员的劳动成果.转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27186557 測试例子简单介绍 Cocos2d-x ...

  7. Oracle触发器简单入门记录

    写在前面: 最近,老项目新增了日报优化的需求,丽姐让我用触发器去实现当数据插入或者更新的时候,实现对日报表数据更新操作.嗯嗯嗯呢,之前学习数据库的时候,有碰到过触发器,但都是一跳而过,也没怎么去真正的 ...

  8. 27:简单错误记录SimpleErrorLog

    题目描述 开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号. 处理: 1. 记录最多8条错误记录,循环记录,对相同的错误记录(净文件名称和行号完全匹配)只记录一条,错误计数增加: ...

  9. 【转】JS回调函数--简单易懂有实例

    JS回调函数--简单易懂有实例 初学js的时候,被回调函数搞得很晕,现在回过头来总结一下什么是回调函数. 我们先来看看回调的英文定义:A callback is a function that is ...

随机推荐

  1. JVM 自动内存管理:对象判定和回收算法

  2. 基于 HTML5 WebGL 的 3D SCADA 主站系统

    这个例子的初衷是模拟服务器与客户端的通信,我把整个需求简化变成了今天的这个例子.3D 的模拟一般需要鹰眼来辅助的,这样找产品以及整个空间的概括会比较明确,在这个例子中我也加了,这篇文章就算是我对这次项 ...

  3. 申请9位数QQ

    官网:QQ注册第一步:下面手机号不要填写 第二步:验证 第三步:开始填写手机号 注:不行就多试着几次就可以了,是不是很惊喜啊!(漏洞,被腾讯发现就不行了喽)

  4. SpringMVC源码之Controller查找原理

    摘要 本文从源码层面简单讲解SpringMVC的处理器映射环节,也就是查找Controller详细过程. SpringMVC请求流程 Controller查找在上图中对应的步骤1至2的过程 Sprin ...

  5. 深度优化LNMP之MySQL

    MySQL数据库优化框架体系 1.硬件层面优化 2.操作系统层面优化 3.MySQL数据库层面优化 4.MySQL安全优化 5.网站集群架构上的优化 6.MySQL流程.制度控制优化 1 硬件层面优化 ...

  6. viim命令行模式查找替换

    1.查找 /   向上查找 ? 向下查找 2.替换 1.:s/vivian/sky/ 替换当前行第一个 vivian 为 sky :s/vivian/sky/g 替换当前行所有 vivian 为 sk ...

  7. SQL Server判断是否满足日期格式(YYYYMMDD)以及中文等判断,格式化为YYYY-MM-DD

    SQL Server判断是否满足日期格式(YYYYMMDD)以及中文等判断: 在做sql数据的正确性审核中,需要判断数据是否满足日期格式,网上找不到相关的资料,于是自己花了半天写了一个简单的函数 具体 ...

  8. 使Tomcat指向指定的JDK目录

    1,修改bin文件夹下面的catalina.bat文件,把如下内容 rem ----- Execute The Requested Command -------------------------- ...

  9. Python基础篇(六)

    retun空值,后面的语句将不再被执行 >>> def test(): ...    print("just a test!") ...    return .. ...

  10. 2018/1/19 Netty学习笔记(一)

    这段时间学了好多好多东西,不过更多是细节和思想上的,比如分布式事物,二次提交,改善代码质量,还有一些看了一些源码什么的; 记录一下真正的技术学习,关于Netty的学习过程; 首先说Netty之前先说一 ...