java面试-synchronized底层实现机制
一、synchronized的三种应用方式
1、修饰实例方法,锁是当前实例对象,进入同步代码前要获得当前实例的锁
/**
* synchronized修饰实例方法,当前线程的锁是实例对象accountingSync
* 当一个线程正在访问一个对象的synchronized实例方法,那么其他线程不能访问该对象的其他synchronized方法
* 一个对象只有一把锁
*/
public class AccountingSync implements Runnable { static AccountingSync accountingSync = new AccountingSync();
//共享资源
static int i = 0;
static int j = 0; public synchronized void increase() {
i++;
} @Override
public void run() {
for(int i =0;i<1000000;i++){
synchronized (this){
increase();
}
}
} public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(accountingSync);
Thread thread2 = new Thread(accountingSync);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(i);
}
}
/**
* thread1访问实例对象obj1的synchronized方法,thread2访问实例对象obj1的synchronized方法
* 这样是允许的,因为两个实例对象锁并不相同。
* 此时如果两个线程操作数据非共享,线程安全有保证,如果数据共享,线程安全无法保证
*
*/
public class AccountingSyncBad implements Runnable { static int i = 0; public synchronized void increase() {
i++;
} @Override
public void run() {
for (int i = 0; i < 1000000; i++) {
increase();
}
} public static void main(String[] args) throws InterruptedException{
//new新实例
Thread thread1 = new Thread(new AccountingSyncBad());
//new新实例
Thread thread2 = new Thread(new AccountingSyncBad());
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(i);
}
}
2、修饰静态方法,锁是当前类的 class对象,进入同步代码前要获得当前类对象的锁
public class AccountingSyncClass implements Runnable{
static int i = 0;
/**
* synchronized作用于静态方法,锁是当前class对象
*/
public static synchronized void increase() {
i++;
}
/**
* increase4Obj方法是实例方法,其对象锁是当前实例对象,
* 如果别的线程调用该方法,将不会产生互斥现象,毕竟锁对象不同,
* 但我们应该意识到这种情况下可能会发现线程安全问题(操作了共享静态变量i)。
*/
public synchronized void increase4Obj(){
i++;
}
@Override
public void run() {
for (int i = 0; i < 1000000; i++) {
increase();
// increase4Obj();
}
}
public static void main(String[] args) throws InterruptedException{
//new新实例
Thread thread1 = new Thread(new AccountingSyncClass());
//new新实例
Thread thread2 = new Thread(new AccountingSyncClass());
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(i);
}
}
3、修饰代码块
synchronized(this) 锁是当前实例对象,
synchronized(AccountingSync.class) 锁是class对象
二、synchronized代码块底层原理
synchronized代码块是由一对monitorenter和monitorexit指令实现的,Monitor对象是同步的基本实现单元。
三、java虚拟机对Synchronized的优化
1、当没有竞争出现时,默认会使用偏斜锁。JVM 会利用 CAS操作,在对象头上的Mark Word部分设置线程ID,以表示这个对象偏向于当前线程,所以并不涉及真正的互斥锁。这样做的假设是基于在很多应用场景中,大部分对象生命周期中最多会被一个线程锁定,使用偏斜锁可以降低无竞争开销。
2、有竞争出现时,当有另外的线程试图锁定某个已经被偏斜锁锁定的对象,jvm就会撤销revoke偏斜锁,并切换到轻量级锁。轻量级锁依赖CAS操作Mark Word来试图获取锁,如果成功,就使用轻量级锁,否则继续升级未重量级锁
PS:锁降级也是存在的,当JVM进入SafePoint安全点的时候,会检查是否有闲置的Monitor,然后试图进行降级。
java面试-synchronized底层实现机制的更多相关文章
- JAVA面试常见问题之锁机制篇
1.说说线程安全问题,什么是线程安全,如何保证线程安全 线程安全:就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用.不 ...
- java多线程synchronized底层实现
一直想把这个特别重要的关键词的底层实现搞明白.(当然现在也没有完全明白,如果有错误以后修改这篇文章) 首先,这个关键词synchronize可以说是个语法糖,它的具体用法网上很多博客都讲的比较明了了. ...
- java面试-synchronized与lock有什么区别?
1.原始构成: synchronized是关键字,属于JVM层面,底层是由一对monitorenter和monitorexit指令实现的. ReentrantLock是一个具体类,是API层面的锁. ...
- java面试-CAS底层原理
一.CAS是什么? 比较并交换,它是一条CPU并发原语. CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B.当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什 ...
- Java面试底层原理
面试发现经常有些重复的面试问题,自己也应该学会记录下来,最好自己能做成笔记,在下一次面的时候说得有条不紊,深入具体,面试官想必也很开心.以下是我个人总结,请参考: HashSet底层原理:(问了大几率 ...
- 面试突击39:synchronized底层是如何实现的?
想了解 synchronized 是如何运行的?就要先搞清楚 synchronized 是如何实现? synchronized 同步锁是通过 JVM 内置的 Monitor 监视器实现的,而监视器又是 ...
- java 多线程 synchronized与lock的通信机制等问题,结合相应实例说明
1. 利用多线程实现如下需求: 写两个线程,一个线程打印1~52,另一个线程打印A~Z,打印顺序是12A34B...5152Z: 2. 使用synchronized 实现 public class T ...
- java多线程02-----------------synchronized底层实现及JVM对synchronized的优化
java多线程02-----------------synchronized底层实现及JVM对synchronized的优化 提到java多线程,我们首先想到的就是synchronized关键字,它在 ...
- 死磕Synchronized底层实现,面试你还怕什么?
关于synchronized的底层实现,网上有很多文章了.但是很多文章要么作者根本没看代码,仅仅是根据网上其他文章总结.照搬而成,难免有些错误:要么很多点都是一笔带过,对于为什么这样实现没有一个说法, ...
随机推荐
- Flutter 学习路径
Flutter 学习路径 docs https://flutter.dev/docs https://flutter.dev/community/china https://flutter-io.cn ...
- flutter 让app跟随系统的theme
首先你需要在"MaterialApp"设置两套theme MaterialApp( theme: myTheme, // light darkTheme: ThemeData.da ...
- 【python接口自动化】- 对接各大数据库
相信很多小伙伴在使用python进行自动化测试的时候,都会涉及到数据库数据校验的问题,在前面的随笔中就已经有讲过连接mysql的使用,今天给大家汇总一下python对接几大常用的数据库操作的方法!众所 ...
- 使用RSEM进行转录组测序的差异表达分析
仍然是两年前的笔记 1. prepare-reference 如果用RSEM对比对后的bam进行转录本定量,则在比对过程中要确保比对用到的索引是由rsem-prepare-reference产生的. ...
- 使用hive增量更新
目录 1.增量更新 2.对第一种情况 2.1.准备工作 2.2.更新数据 3.对第二种情况 3.1.准备工作 3.2.方法1 3.3.方法2 参考文末文章,加上自己的理解. 1.增量更新 有一个 ba ...
- 「TcaplusDB知识库」概念(表、键、记录、索引)
TcaplusDB作为一款NoSQL数据库,语法与传统的SQL关系库有所差异.本文将详细介绍TcaplusDB表.记录.索引这三个数据库中常用术语在TcaplusDB中的概念与意义. 术语\概念 ...
- 解决bs4在python中出现“ImportError: cannot import name ‘HTMLParseError‘”错误
在使用BeautifulSoup4时候出现了ImportError: cannot import name 'HTMLParseError'的错误. 根本原因是BeautifulSoup在4.4.0以 ...
- 微信小程序登录流程解析
小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识openid,快速建立小程序内的用户体系. 登录流程时序: 1.首先,调用 wx.login获取code ,判断用户是否授权读取用户 ...
- Go的结构体
目录 结构体 一.什么是结构体? 二.结构体的声明 三.创建结构体 1.创建有名结构体 2.结构体初始化 2.1 按位置传参 2.2 按关键字传 3.创建匿名结构体 四.结构体的类型 五.结构体的默认 ...
- 使用lua-nginx模块实现请求解析与调度
系统版本及需求: OS:CentOS 7.7.1908 OpenResty:1.15.8.2 目录 描述 安装配置 安装openresty 使用示例 HTTP请求复制 HTTP报文解析 总结 描述 l ...