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类 ...
随机推荐
- MacType
#前言 这几天实在是嫌弃Win10垃圾的字体渲染效果--发虚模糊,索性从网上找了个系统字体渲染软件即MacType给系统字体改头换面. #使用效果 这里贴出两个场景的效果对比(单击图片查看具体效果) ...
- 【学习Koa】原生koa2 静态资源服务器例子
实现思路 首先读取当前路径下所有的文件和文件夹 当去点击某个列表项时判断其实文件还是文件夹,文件的话直接读取,文件夹则再次利用上一个步骤读取并展示 文件结构 代码 index.js 入口文件 cons ...
- ACM-单词接龙
题目描述:单词接龙 问题描述:单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们己知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙" 中出现 ...
- .net微软企业库的事务回滚
事务是自定义的一个操作序列. 其中的操作要么全部执行要么全部不执行,是一个不可分割的工作单位.通过事务,SQL Server能将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性. Databa ...
- (二)requests模块
一 requests模块 概念: python中原生的基于网络请求的模块,模拟浏览器进行请求发送,获取页面数据 安装: pip install requests 二 requests使用的步骤 1 指 ...
- js 混合构造原型 运用
1.给10个div添加点击事件 <body> <div class="sd">sdss</div> <div class="sd ...
- 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ
鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...
- Frequently arduino function
unctions 功能if(Serial) ...
- 19 01 16 djano 视图以及url
视图 后台管理页面做好了,接下来就要做公共访问的页面了.当我们刚刚在浏览器中输入 http://127.0.0.1:8000/admin/ 之后,浏览器显示出了后台管理的登录页面,那有没有同学想过这个 ...
- C++编程学习(四)声明/枚举
一.typedef 声明 typedef 为一个已有的类型取一个新的名字 typedef int num;//feet是int的另一个名字num a;//a是int类型 二.枚举类型 enum col ...