Java Keyword Synchronized 学习记录
Synchronized
Java编程思想:每个对象都包含了一把锁(也叫作“监视器”),它自动成为对象的一部分,调用任何synchronized方法时,对象就会被锁定,不可再调用那个对象的其他任何synchronized 方法,除非第一个方法完成了自己的工作,并解除锁定。
特点:Jvm层面,非公平,悲观,独占,可重入,重量级。
作用:修饰方法和代码块。
修饰方法和代码块
synchronized修饰静态方法,我们可以称其为“类锁”,即只要有一个线程实例对象获取该锁,其他线程实例对象都需要等待。修饰非静态方法,我们称之为对象锁,即不同的线程实例对象是可以调用同一类下的同步方法。
/**
* @PackageName com.a.squirrel.synchronize
* @Author: squirrel
* @Date: 2018/6/25 10:04
* @Description: synchronized解析辅助类
*/
public class SynchronizedDescription {
private String tmpStr;
private int tmpInt;
/**
* @Author squirrel
* @Description 非静态同步方法
* @Date 2018/6/25
* @Param [synchronizedDescription]
* @return
**/
public synchronized void testSynchronizedMethod(SynchronizedDescription synchronizedDescription){
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:==========我是非静态同步方法=======");
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:调用非静态同步方法时间为:"+getNowTime());
try {
Thread.sleep(5000);// 当前线程休眠5s,休眠过程中不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* @Author squirrel
* @Description 同步代码块
* @Date 2018/6/25
* @Param [synchronizedDescription]
* @return
**/
public void testSynchronizedBlockMethod(SynchronizedDescription synchronizedDescription){
synchronized (synchronizedDescription){// 锁定实例对象
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:==========我是同步代码块=======");
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:调用同步代码块时间为:"+getNowTime());
try {
Thread.sleep(2000);// 当前线程休眠2s,休眠过程中不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* @Author squirrel
* @Description 静态同步方法
* @Date 2018/6/25
* @Param [synchronizedDescription]
* @return
**/
public synchronized static void testSynchronizedStaticMethod(SynchronizedDescription synchronizedDescription){
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:==========我是静态同步方法=======");
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:调用静态同步方法时间为:"+getNowTime());
try {
Thread.sleep(10000);// 当前线程休眠10s,休眠过程中不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* @Author squirrel
* @Description 获取当前时间
* @Date 2018/6/25
* @Param []
* @return java.lang.String
**/
private static String getNowTime(){
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
public SynchronizedDescription(String tmpStr, int tmpInt) {
this.tmpStr = tmpStr;
this.tmpInt = tmpInt;
}
public String getTmpStr() {
return tmpStr;
}
public void setTmpStr(String tmpStr) {
this.tmpStr = tmpStr;
}
public int getTmpInt() {
return tmpInt;
}
public void setTmpInt(int tmpInt) {
this.tmpInt = tmpInt;
}
}
/**
* @PackageName com.a.squirrel.synchronize
* @Author: squirrel
* @Date: 2018/6/25 10:10
* @Description: 测试类
*/
public class TestSynchronized {
public static void main(String[] args) {
// 创建阻塞队列
final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(100);
// 创建线程池
final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2,20,60, TimeUnit.SECONDS,queue);
threadPool.allowCoreThreadTimeOut(true);
for (int i =0;i<100;i++){
threadPool.execute(new Runnable() {
@Override
public void run() {
final String tmpStr = Thread.currentThread().getName();
final String[] split = tmpStr.split("-");
int tmpInt = Integer.parseInt(split[split.length-1]);
SynchronizedDescription synchronizedDescription = new SynchronizedDescription(tmpStr,tmpInt);
// 调用同步代码块
synchronizedDescription.testSynchronizedBlockMethod(synchronizedDescription);
// 调用非静态同步方法
synchronizedDescription.testSynchronizedMethod(synchronizedDescription);
// 调用静态同步方法
synchronizedDescription.testSynchronizedStaticMethod(synchronizedDescription);
}
});
}
}
}
运行结果可以验证以上结论:

下面我们变更同步代码块的同步对象:
/**
* @Author squirrel
* @Description 同步代码块
* @Date 2018/6/25
* @Param [synchronizedDescription]
* @return
**/
public void testSynchronizedBlockMethod(SynchronizedDescription synchronizedDescription){
synchronized (SynchronizedDescription.class){// 锁定类对象
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:==========我是同步代码块=======");
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:调用同步代码块时间为:"+getNowTime());
try {
Thread.sleep(2000);// 当前线程休眠2s,休眠过程中不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

由上图我们可以得出一个结论,这里借用一张图来说明一下这个结论:

实现原理:
深入理解Java虚拟机:对象在内存中存储的布局可以分为3块区域:对象头,实例数据和对齐填充。

synchronized对象锁其指针指向的是一个monitor对象,每个对象实例都会有一个 monitor,其中monitor可以与对象一起创建销毁,也可以在线程试图获取对象锁时自动生成。在执行monitorenter指令时,首先要尝试获取对象锁,如果这个对象没有被锁定,或者当前线程已经拥有了这个对象的锁,那么就把锁计数器加1,当执行monitorexit指令时,释放锁同时锁计数器也会减1。


Java Keyword Synchronized 学习记录的更多相关文章
- Java Keyword Static 学习记录
Static Java编程思想:一旦将什么东西设为static,数据或方法就不会同那个类的任何对象实例联系到一起. 特点:随着类的加载而加载,随着类的销毁而销毁. 作用:可以修饰成员变量,代码块,方法 ...
- java 项目相关 学习记录
一位资深程序员大牛给予Java初学者的学习路线建议 [任何时期都可以好好看看] https://www.imooc.com/article/8993 https://www.jianshu.com/ ...
- 转:java高并发学习记录-死锁,活锁,饥饿
死锁 两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去. 为什么会产生死锁: ① 因为系统资源不足. ② 进程运行推进的顺序不合适. ③ ...
- JAVA 动态代理学习记录
打算用JAVA实现一个简单的RPC框架,看完RPC参考代码之后,感觉RPC的实现主要用到了两个方面的JAVA知识:网络通信和动态代理.因此,先补补动态代理的知识.---多看看代码中写的注释 参考:Ja ...
- [Hanani]JAVA大数相关学习记录
1.Basic remains 题目链接 涉及内容: |大数读入|大数模|大数进制读入时转化为十进制|大数输出时转化为其他进制输出| import java.io.*; import java.mat ...
- java一周学习记录(2017/12/2)
姓名:Danny 日期:2017/12/2 周日 周一 周二 周三 周四 周五 周六 所花时间 120 150 190 150 180 28 ...
- 阿里巴巴java开发手册学习记录,php版
一.编程规约 (一)命名风格 1.目录使用小写+下划线 home,view,model,admin_view 2.类 UpperCamelCase PhpMailer方法 lowerCamelCase ...
- [SRH.Docker] HBase Java 第一天学习记录
主要对HBase Table 的 简单操作, 直接上代码吧!!! http://pan.baidu.com/s/1hqzTTze ui92
- Java 类引入 学习记录规整
之前觉得声明一个类,再把另一个包内的声明数值用第一个类打印出来就可以了(加入引入包类) 结果发现是不对的 看了看demo 得出正确结果 ImportTest 被运行 引入下面的Import类 ...
随机推荐
- HTML的文档结构与语法(一)
一.走进Web开发 Web运行的原理: 二.HTML 1.1什么是html HTML是用来描述网页的一种语言 HTML指的是超文本标记语言(Hyper Text Markup Language) 超文 ...
- android 动画基础绘——view 动画(二)[补]
前言 这个是对view 动画的补充,是一些view 动画的特殊使用场景. 回顾第一篇关于view 动画的,我介绍到view的动画都是针对元素本身的. 当我们开发view动画的时候,我们看到几个元素在做 ...
- Vulkan SDK 之 Shaders
Compiling GLSL Shaders into SPIR-V 1.SPIR-V 是vulkan的底层shader语言.GLSL可以通过相关接口转换为SPIR-V. Creating Vulka ...
- 从零开始学C++(0 简介)
2020年,给自己定一个新目标————开始写技术博客,将之前所学的内容重新复习并整理成一系列的文章,一来可以让自己对这些基础知识更加熟悉,二来方便于以后的复习查阅. 以前自己都是以笔记的形式将知识点记 ...
- 033-PHP取1-100的随机数
<?php // 生成一个随机数 // 从1到100中取得随机数 for ($index = 0; $index < 100; $index++) { $number = (rand() ...
- 经典SQL50句
50个常用的sql语句 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,T ...
- mysql 分组查询教程
1.分组 分组就是将一个“数据集”划分成若干个“小区域”,然后针对若干个“小区域”进行数据处理. 2.分组的特点 1.)group by的含义:将查询结果按照1个或多个字段进行分组,字段值相同的为一组 ...
- silicon射频发射器 SI4010-C2-GSR
Si4010是第一款系统级的自动天线调谐发射器,具有专利的调谐电路,可自动微调天线以达到最佳效果,以及恒定的输出功耗.PCB环形天线的制造公差和环境改变,将会引起发射频率的变化,从而可能导致天线的效率 ...
- oracle(4)----空值说明
1. 含义:空值(null)表示未知或者暂时不存在的数据,任何类型(没有约束的条件下)都可以取值null:2. 插入null值: insert into stu (id,name) values(3, ...
- web应用中并发控制的实现,各种锁的集合
参考:http://blog.csdn.net/xiangwanpeng/article/details/55106732 B/S构架的应用越来越普及,但由于它有别于C/S构架的特殊性,并发控制始终没 ...