synchronized锁住的是代码还是对象,以及synchronized底层实现原理
synchronized (this)原理:涉及两条指令:monitorenter,monitorexit;再说同步方法,从同步方法反编译的结果来看,方法的同步并没有通过指令monitorenter和monitorexit来实现,相对于普通方法,其常量池中多了ACC_SYNCHRONIZED标示符。
JVM就是根据该标示符来实现方法的同步的:当方法被调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取monitor,获取成功之后才能执行方法体,方法执行完后再释放monitor。在方法执行期间,其他任何线程都无法再获得同一个monitor对象。
synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行。synchronized既可以加在一段代码上,也可以加在方法上。
class Sync {
public synchronized void test() {
System.out.println("test开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test结束..");
}
}
class MyThread extends Thread {
public void run() {
Sync sync = new Sync();
sync.test();
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread thread = new MyThread();
thread.start();
}
}
}
运行结果: test开始.. test开始.. test开始.. test结束.. test结束.. test结束..
上面的程序起了三个线程,同时运行Sync类中的test()方法,虽然test()方法加上了synchronized,但是还是同时运行起来,貌似synchronized没起作用。
注意:synchronized()锁住的是括号里的对象,而不是代码。对于非static的synchronized方法,锁的就是对象本身也就是this。
则可以这样:
class Sync {
public void test() {
synchronized (Sync.class) {
System.out.println("test开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test结束..");
}
}
}
class MyThread extends Thread {
public void run() {
Sync sync = new Sync();
sync.test();
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread thread = new MyThread();
thread.start();
}
}
}
运行结果: test开始.. test结束.. test开始.. test结束.. test开始.. test结束..
上面代码用synchronized(Sync.class)实现了全局锁的效果。
static synchronized方法,static方法可以直接类名加方法名调用,方法中无法使用this,所以它锁的不是this,而是类的Class对象,所以,static synchronized方法也相当于全局锁,相当于锁住了该整个方法的代码段。
synchronized锁住的是代码还是对象,以及synchronized底层实现原理的更多相关文章
- synchronized锁住的是代码还是对象
不同的对象 public class Sync { public synchronized void test() { System.out.println("test start" ...
- Java线程同步:synchronized锁住的是代码还是对象
所以我们在用synchronized关键字的时候,能缩小代码段的范围就尽量缩小,能在代码段上加同步就不要再整个方法上加同步.这叫减小锁的粒度,使代码更大程度的并发.原因是基于以上的思想,锁的代码段太长 ...
- Java并发,synchronized锁住的内容
synchronized用在方法上锁住的是什么? 锁住的是当前对象的当前方法,会使得其他线程访问该对象的synchronized方法或者代码块阻塞,但并不会阻塞非synchronized方法. 脏读 ...
- 【synchronized锁】通过synchronized锁 反编译查看字节码指令分析synchronized关键字修饰方法与代码块的区别
前提: 首先要铺垫几个前置的知识: Java中的锁如sychronize锁是对象锁,Java对象头中具有标识位,当对象锁升级为重量级锁时,重量级锁的标识位会指向监视器monitor, 而每个Java对 ...
- Java多线程5:Synchronized锁机制
一.前言 在多线程中,有时会出现多个线程对同一个对象的变量进行并发访问的情形,如果不做正确的同步处理,那么产生的后果就是“脏读”,也就是获取到的数据其实是被修改过的. 二.引入Synchronized ...
- java synchronized究竟锁住的是什么
刚学java的时候,仅仅知道synchronized一个线程锁.能够锁住代码,可是它真的能像我想的那样,能够锁住代码吗? 在讨论之前先看一下项目中常见关于synchronized的使用方法: publ ...
- java内置锁实现锁住代码块方案(同一个对象或锁住整个类.class)
我们看一个例子: class Demo { public synchronized void test() { System.out.println("test方法开始执行,当前线程为:&q ...
- 015-线程同步-synchronized几种加锁方式、Java对象头和Monitor、Mutex Lock、JDK1.6对synchronized锁的优化实现
一.synchronized概述基本使用 为确保共享变量不会出现并发问题,通常会对修改共享变量的代码块用synchronized加锁,确保同一时刻只有一个线程在修改共享变量,从而避免并发问题. syn ...
- Java synchronized(this)锁住的是什么
synchronized锁住的是括号里面的对象,而不是代码. 对于非static的synchronized方法,锁的就是对象本身,也就是this.
随机推荐
- [JZOJ5399]:Confess(随机化)
题目描述 小$w$隐藏的心绪已经难以再隐藏下去了. 小$w$有$n+1$(保证$n$为偶数)个心绪,每个都包含了$[1,2n]$的一个大小为$n$的子集. 现在他要找到隐藏的任意两个心绪,使得他们的交 ...
- win7系统安装Mysql5.7
1.下载mysql的zip包 把zip包解压到指定的目录,目录不能有中文和空格 2.进入%mysql%目录(注:%mysql%是解压目录,我的是:D:\JavaTool\mysql) 在%mysql% ...
- auth 认证组件的补充
Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Djang ...
- [翻译]C#中异步方法的性能特点
翻译自一篇博文,原文:The performance characteristics of async methods in C# 异步系列 剖析C#中的异步方法 扩展C#中的异步方法 C#中异步方法 ...
- 数据库-MongoDb
*本文总结下使用Mongodb遇到的问题: 1. 安装完MongoDb后先启动服务端,然后再启动客户端: 直接上图: 注意点:mongod.exe :是用来连接到mongo数据库服务器的,即服务器端. ...
- 运算 Kotlin(3)
运算Kotlin支持数字运算的标准集,运算被定义为相应的类成员(但编译器会将函数调用优化为相应的指令) . 参见运算符重载.对于位运算,没有特殊字符来表示,而只可用中缀方式调用命名函数,例如:val ...
- UVA 122 -- Trees on the level (二叉树 BFS)
Trees on the level UVA - 122 解题思路: 首先要解决读数据问题,根据题意,当输入为“()”时,结束该组数据读入,当没有字符串时,整个输入结束.因此可以专门编写一个rea ...
- GetRGB下载
下载地址:https://pan.baidu.com/s/11EyUPa2WxhIgdsTRZtj_eg 07年6-8月做的,用于屏幕取色. 2019年8月30日13点50分
- Windows环境下Mysql 5.7读写分离之使用mysql-proxy练习篇
本文使用mysql-proxy软件,结合mysql读写分离,实现实战练习. 前期准备: 三台机器: 代理机,IP:192.168.3.33 mysql Master,IP:192.168.3.32 m ...
- Prism学习笔记-模块之间通信的几种方式
在开发大型复杂系统时,我们通常会按功能将系统分成很多模块,这样模块就可以独立的并行开发.测试.部署.修改.使用Prism框架设计表现层时,我们也会遵循这个原则,按功能相关性将界面划分为多个模块,每个模 ...