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 学习记录的更多相关文章

  1. Java Keyword Static 学习记录

    Static Java编程思想:一旦将什么东西设为static,数据或方法就不会同那个类的任何对象实例联系到一起. 特点:随着类的加载而加载,随着类的销毁而销毁. 作用:可以修饰成员变量,代码块,方法 ...

  2. java 项目相关 学习记录

    一位资深程序员大牛给予Java初学者的学习路线建议  [任何时期都可以好好看看] https://www.imooc.com/article/8993 https://www.jianshu.com/ ...

  3. 转:java高并发学习记录-死锁,活锁,饥饿

    死锁 两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去. 为什么会产生死锁: ① 因为系统资源不足. ② 进程运行推进的顺序不合适.    ③ ...

  4. JAVA 动态代理学习记录

    打算用JAVA实现一个简单的RPC框架,看完RPC参考代码之后,感觉RPC的实现主要用到了两个方面的JAVA知识:网络通信和动态代理.因此,先补补动态代理的知识.---多看看代码中写的注释 参考:Ja ...

  5. [Hanani]JAVA大数相关学习记录

    1.Basic remains 题目链接 涉及内容: |大数读入|大数模|大数进制读入时转化为十进制|大数输出时转化为其他进制输出| import java.io.*; import java.mat ...

  6. java一周学习记录(2017/12/2)

    姓名:Danny                               日期:2017/12/2 周日 周一 周二 周三 周四 周五 周六 所花时间 120 150 190 150 180 28 ...

  7. 阿里巴巴java开发手册学习记录,php版

    一.编程规约 (一)命名风格 1.目录使用小写+下划线 home,view,model,admin_view 2.类 UpperCamelCase PhpMailer方法 lowerCamelCase ...

  8. [SRH.Docker] HBase Java 第一天学习记录

    主要对HBase Table 的 简单操作, 直接上代码吧!!! http://pan.baidu.com/s/1hqzTTze       ui92

  9. Java 类引入 学习记录规整

    之前觉得声明一个类,再把另一个包内的声明数值用第一个类打印出来就可以了(加入引入包类) 结果发现是不对的 看了看demo  得出正确结果    ImportTest 被运行 引入下面的Import类 ...

随机推荐

  1. 使用CORDIC算法求解角度正余弦及Verilog实现

    本文是用于记录在了解和学习CORDIC算法期间的收获,以供日后自己及他人参考:并且附上了使用Verilog实现CORDIC算法求解角度的正弦和余弦的代码.简单的testbench测试代码.以及在Mod ...

  2. 浅谈arduino的bootloader

    在arduino的板子上,作为核心的avr单片机往往都会烧录一个bootloader,这个叫做bootloader的东东其实是arduino研发团队针对arduino板子开发的一小段代码,借助于这段代 ...

  3. [LeetCode] 930. Binary Subarrays With Sum 二元子数组之和

    In an array A of 0s and 1s, how many non-empty subarrays have sum S? Example 1: Input: A = [1,0,1,0, ...

  4. linux命令,个人的日记本

    查看所有服务 chkconfig --list service httpd status ps -aux | grep svn

  5. SQL优化工具 - SQL Server Profiler与数据库引擎优化顾问

    最近项目做到几千个学生分别去人脸识别记录(目前约630000行)中查询最后一次记录,可想而知性能这块是个麻烦.于是乎,GET到了SQL Server Profiler和数据库引擎优化顾问这俩工SHEN ...

  6. 联系我们地图坐标展示js

    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=6d88 ...

  7. css布局 -双飞翼布局&圣杯布局

    一,双飞翼布局 左右两边固定,中间可以随着浏览器放大和缩小 <!DOCTYPE html> <html lang="en"> <head> &l ...

  8. 二、环境安装:yarn

    依赖管理工具安装yarn 可参考前几篇文章 1.必须安装nodejs 注意:安装nodejs稳定版本 2.安装cnpm用cnpm替代npm 地址:http://npm.taobao.org/安装cnp ...

  9. hdu 2578 Dating with girls(1) 满足条件x+y=k的x,y有几组

    Dating with girls(1) Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  10. assert和hasattr,getattr,setattr

    assert hasattr(self, 'initial_data'), ( 'Cannot call `.is_valid()` as no `data=` keyword argument wa ...