Java synchronized到底锁住的是什么?
使用环境:多线程java程序中。
作用:在多线程的环境下,控制synchronized代码段不被多个线程同时执行。synchronized既可以加在一段代码上,也可以加在方法上。
使用:synchronized锁住的是括号里的对象,而不是代码。对于非static的synchronized方法,锁的就是对象本身也就是this。
通过以下两个案例说明:
//包含了synchronized 方法的类
public class SynchronizedMethod {
public synchronized void test()
{
System.out.println("线程开始..");
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("线程结束..");
}
} //测试类
public class MyThread extends Thread{
public void run(){
SynchronizedMethod clazz = new SynchronizedMethod();
clazz.test();
} public static void main(String[] args) {
for(int i=0;i<3;i++)
{
Thread thread = new MyThread();
thread.start();
}
} } 执行结果:
线程开始..
线程开始..
线程开始..
线程结束..
线程结束..
线程结束..
分析上述执行结果可知:
当main方法执行时,分别创建了三个MyThread对象,而这三个对象又各自创建了独立的 SynchronizedMethred类,虽然使用了test方法使用了synchronized方法修饰,但是synchronized锁住的是三个独立的对象,因为三个对象各自分别执行了test方法。
因此,可以修改代码,让三个线程使用同一个SynchronizedMethod对象:
//修改测试类代码如下,使用同一对象调用test方法
public class MyThread extends Thread{
/**
* Author:LearnAndGet
*/
private SynchronizedMethod sync;
public MyThread(SynchronizedMethod sync)
{
this.sync = sync;
}
public void run(){
sync.test();
}
public static void main(String[] args) {
SynchronizedMethod sync = new SynchronizedMethod();
for(int i=0;i<3;i++)
{
MyThread thread = new MyThread(sync);
thread.start();
}
}
}
运行结果:
线程开始..
线程结束..
线程开始..
线程结束..
线程开始..
线程结束..
分析上述结果:由于每次新线程启动,使用的同一对象sync,因此synchronized生效了。
当然,更常用的方法是:使用schronized锁住这个类对应的Class对象:
public class SynchronizedMethod {
public void test()
{
//将代码块使用synchronized锁住
synchronized(SynchronizedMethod.class)
{
System.out.println("线程开始..");
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("线程结束..");
}
}
}
使用上述代码后,即使每次创建不同的SynchronizedMethod对象,执行其test方法时,因为synchronized锁住了SynchronizedMethod类对应的class对象,所以每次只能有一个SynchronizedMethod的对象获取锁,直到该锁获得释放,其他SynchronizedMethod对象都无法执行其方法。
上述代码中,通过使用 synchronized(SynchronizedMethod.class)实现了全局锁的效果
除此之外,使用 static synchronized一起修饰方法时,static方法可以直接类名加方法名调用,方法中无法使用this,所以它锁的不是this,而是类的Class对象,所以,static synchronized方法也相当于全局锁,相当于锁住了代码段。
Java synchronized到底锁住的是什么?的更多相关文章
- synchronized到底锁住的是谁?
本文代码仓库:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/sync 先来一道校招级并发编程笔试题 题 ...
- java synchronized究竟锁住的是什么
刚学java的时候,仅仅知道synchronized一个线程锁.能够锁住代码,可是它真的能像我想的那样,能够锁住代码吗? 在讨论之前先看一下项目中常见关于synchronized的使用方法: publ ...
- Java synchronized(this)锁住的是什么
synchronized锁住的是括号里面的对象,而不是代码. 对于非static的synchronized方法,锁的就是对象本身,也就是this.
- Java同步方法:synchronized到底锁住了谁?
目录 前言 同步方法 类的成员方法 类的静态方法 同步代码块 总结 其他同步方法 参考资料 前言 相信不少同学在上完Java课后,对于线程同步部分的实战,都会感到不知其然. 比如上课做实验的时候,按着 ...
- java synchronized类锁,对象锁详解(转载)
觉得还不错 留个记录,转载自http://zhh9106.iteye.com/blog/2151791 在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看 ...
- 由Java 15废弃偏向锁,谈谈Java Synchronized 的锁机制
Java 15 废弃偏向锁 JDK 15已经在2020年9月15日发布,详情见 JDK 15 官方计划.其中有一项更新是废弃偏向锁,官方的详细说明在:JEP 374: Disable and Depr ...
- JAVA synchronized关键字锁机制(中)
synchronized 锁机制简单的用法,高效的执行效率使成为解决线程安全的首选. 下面总结其特性以及使用技巧,加深对其理解. 特性: 1. Java语言的关键字,当它用来修饰一个方法或者一个代码块 ...
- 关于synchronized无法锁住Integer原因
原因 在多线程的时候,为了保证数据安全,必须在修改数据时使用线程同步,java中的synchronized用来实现线程同步.线程列队. 学完多线程基础的我,写一个多线程交替输出1,2,3,4,5... ...
- 关于Synchronized关键字锁住对象的嵌套问题
如果在子关键字代码块中调用了sleep,是否会保留有所的锁?
随机推荐
- synchronized锁住的是代码还是对象,以及synchronized底层实现原理
synchronized (this)原理:涉及两条指令:monitorenter,monitorexit:再说同步方法,从同步方法反编译的结果来看,方法的同步并没有通过指令monitorenter和 ...
- WPF中的Stretch属性
有时候我们在WPF程序中设置了图片的Width和Height,但图片显示出来的宽和高并不是我们预期的效果,这实际上是由于Image的默认Stretch属性导致的 Image的Stretch属性默认为U ...
- java 判断5张牌的组成
题目: 一副牌中发五张扑克牌给你,判断是四条,三带二.三带一加一.两对.一对.顺子.还是什么都不是. 控制台输入: 1,1,1,1,2 示例输出: 四条 Java方法的代码: static Strin ...
- 如何使用hook(非注入dll)
#include <Windows.h> #include <iostream> using namespace std; HHOOK mouseHook; LRESULT _ ...
- H5手机端开发问题汇总及解决方案
前言 少侠,请留步,相见必是缘分,赠与你一部<踏坑秘籍> 扎马步 踏坑第一式 ios竖屏拍照上传,图片被旋转问题 解决方案 // 几个步骤 // 1.通过第三方插件exif-js获取到图片 ...
- 【NOIP2012模拟10.25】旅行
题目 给定一个n行m列的字符矩阵,'.'代表空地,'X'代表障碍.移动的规则是:每秒钟以上下左右四个方向之一移动一格,不能进入障碍. 计算:在空地中随机选择起点和终点(可以重合,此时最短耗时为0),从 ...
- rmq——同步、异步、单向、rocketMQ console、消费模式
官网上下载:rocketmq-all-4.5.0-bin-release 配置环境变量:
- VUE DIV模拟input框的基本处理
关键代码 <div class="dialog-main" :contenteditable= "editable" v-text="notic ...
- MySQL 运维管理平台
github: https://github.com/XiaohaoYu/mysql_platform
- JUnit——Annotation
Annotation是对属性,方法或者类做一个标记 比如@override表示复写了父类中的方法 [1]@Test: 测试方法(说明该方法为测试方法) a)(expected=XXException ...