关于java的Synchronized,你可能需要知道这些(下)
上一篇文章介绍了synchronized的基本使用方法和实现,在实现部分说明了synchronized的底层实现依赖系统互斥锁mutex,但是这个一个重型锁,竞争导致线程阻塞挂起,后续拿到锁后再恢复线程,因为java使用的是1对1的线程模型,这个过程页涉及到了用户态和内核态的转换,比较消耗性能。为了解决这个问题,java1.6引入了“轻量级锁”、“偏向锁”。
1.锁优化
锁的状态分为四种:无锁、偏向锁、轻量级锁,重量级锁,四种锁状态对性能的消耗依次增高,状态的转化也是由无锁向重量级锁转化,这个过程称之为锁的升级,不会出现锁的降级,除非解锁了向无锁状态转换,四种锁状态下对象头前32bit如下(以32bit为例)
锁状态 |
25 bit |
4bit |
1bit |
2bit |
||
23bit |
2bit |
是否是偏向锁 |
锁标志位 |
|||
轻量级锁 |
指向栈中锁记录的指针 |
00 |
||||
重量级锁 |
指向互斥量(重量级锁)的指针 |
10 |
||||
GC标记 |
空 |
11 |
||||
偏向锁 |
线程ID |
Epoch |
对象分代年龄 |
1 |
01 |
|
无锁 |
对象的hashCode |
对象分代年龄 |
0 |
01 |
锁状态转化如下图所示:
基本的转化流程如下(详细可以参考:http://www.cnblogs.com/paddix/p/5405678.html):
一个对象刚开始实例化的时候,没有任何线程来访问它的时候。它是可偏向的,意味着,它现在认为只可能有一个线程来访问它,所以当第一个
线程来访问它的时候,它会偏向这个线程,此时,对象持有偏向锁。偏向第一个线程,这个线程在修改对象头成为偏向锁的时候使用CAS操作,并将
对象头中的ThreadID改成自己的ID,之后再次访问这个对象时,只需要对比ID,不需要再使用CAS在进行操作。
一旦有第二个线程访问这个对象,因为偏向锁不会主动释放,所以第二个线程可以看到对象时偏向状态,这时表明在这个对象上已经存在竞争了,检查原来持有该对象锁的线程是否依然存活,如果挂了,则可以将对象变为无锁状态,然后重新偏向新的线程,如果原来的线程依然存活,则马上执行那个线程的操作栈,检查该对象的使用情况,如果仍然需要持有偏向锁,则偏向锁升级为轻量级锁,(偏向锁就是这个时候升级为轻量级锁的)。如果不存在使用了,则可以将对象回复成无锁状态,然后重新偏向。
轻量级锁认为竞争存在,但是竞争的程度很轻,一般两个线程对于同一个锁的操作都会错开,或者说稍微等待一下(自旋),另一个线程就会释放锁。 但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁膨胀为重量级锁,重量级锁使除了拥有锁的线程以外的线程都阻塞,防止CPU空转。
关于java的Synchronized,你可能需要知道这些(下)的更多相关文章
- Java 多线程 —— synchronized关键字
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- Java的synchronized关键字:同步机制总结
JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块.搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程 ...
- JAVA多线程synchronized详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 当两个并发线程访问同一个对象object中的这个synchronized(this)同 ...
- java中synchronized的用法详解
记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchron ...
- JAVA关键词synchronized的作用
记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchron ...
- java中synchronized的使用方法与具体解释
Java语言的keyword.当它用来修饰一个方法或者一个代码块的时候,可以保证在同一时刻最多仅仅有一个线程运行该段代码. 一.当两个并发线程訪问同一个对象object中的这个synchronized ...
- java同步synchronized
java同步synchronized volatile仅仅用来保证该变量对所有线程的可见性,但不保证原子性. 看下面的这段代码: /** * * @author InJavaWeTrust * */ ...
- 理解java关键字Synchronized(学习笔记)
之前学习了线程的一些相关知识,今天系统的总结下来 目录 1. Java对象在堆内存中的存储结构 2. Monitor管程 3. synchronized锁的状态变换以及优化 4. synchroniz ...
- java中synchronized关键字分析
今天我们来分析一下java中synchronized关键字.首先来看一段java代码:(本地编译环境为mac,jdk1.8的环境) Demo.java package com.example.spri ...
- Java 中 synchronized的用法详解(四种用法)
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码.本文给大家介绍java中 synchronized的用法,对本文感兴趣的朋友一起看看吧 ...
随机推荐
- "共振式”项目管理
"共振式”项目管理--是我第一个提出的吗?:) 脑子里突然想到项目管理的一些事情,然后想到项目其实是有节奏的,项目中的人员其实如果找到了这个节奏,踏准了节奏,一切将是顺风顺水. 刚准备动笔时 ...
- java循环遍历类属性 get 和set值方法
//遍历sqspb类 成员为String类型 属性为空的全部替换为"/"Field[] fields = sqspb.getClass().getDeclaredFields(); ...
- 服务器批量管理软件ansible安装以及配置
1.yum安装(管理主机以及被管理主机都需要安装) yum install epel-release yum install ansible 2.配置管理主机 vim /etc/ansible/hos ...
- Tumblr:我们是如何从 PHP 5 升级到 PHP 7 的
Tumblr 团队经常在寻找新的方式来提升网站的性能.这意味着要给访问量大的代码增加缓存,找到更快的 CDN 配置,或者升级基础软件. 最近,通过一次跨团队的努力,我们将全部 web 服务器战舰从 P ...
- 设置Nginx+php-fpm显示错误信息
Begin 最近在用PHP写后台程序,但是有错误不会显示简直坑爹,全都是200这样的错误代码而已= =... 于是 于是就搜索如何打开错误显示,然后就在博客里面记录一下 修改配置文件 /etc/php ...
- Struts(十六):通过CURD来学习Struts流程及ModelDriven的用法
背景: 从一个Member的增删改查,来了解Struts2的运行原理及学习ModelDriven拦截器.Preparable拦截器. 新建项目实现列表的展示及删除功能: web.xml <?xm ...
- POJ-1556 The Doors---线段相交+最短路
题目链接: https://vjudge.net/problem/POJ-1556 题目大意: 给一个10*10的正方形房间中间用墙隔开每个墙上有两个门,给出门的两个端点坐标求从左边中点走到右边中点所 ...
- js面向对象之公有、私有、静态属性和方法详解
现下,javascript大行其道,对于网站开发人员来说,javascript是必需掌据的一门语言,但随着jquery等框架的流行和使用,许多人对于原生javascript缺乏深入的理解,习惯了函数式 ...
- spring boot / cloud (四) 自定义线程池以及异步处理@Async
spring boot / cloud (四) 自定义线程池以及异步处理@Async 前言 什么是线程池? 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线 ...
- v-bind特性
插值语法不能作用在 HTML 特性上,因此使用 v-bind 指令1.v-bind在一般特性上的使用:如id,src,disabled,checked,selected,name html: < ...