谈谈synchronized
为什么要用synchronized关键字:
synchronized是java的一种内部锁,是一种排他锁,通常也被称为悲观锁,它能够保障原子性,可见性,有序性。
当多个线程去调用同一个方法的时候,如果不用加synchronized锁,就可能出现线程不安全的问题。举个经典的例子,比如两夫妻一个用银行卡,一个用网银同时取同一个账户的钱,
取钱这个操作在银行的后台肯定是一个方法,如果两方同时调用,很有可能造成取了两份的钱,这样肯定是不行的。
synchronized的两种使用方式:
1,synchronized加在方法上
public class T { private int count = 10; public synchronized void m() {
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
} }
2,synchronized代码块
public class T { private int count = 10; public void m() {
synchronized(this) {
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
} }
这里两种方式达到的效果是一样的,我们需要关注以下几点:
1,synchronized锁,锁的是什么东西。其实是锁的一个对象,任意对象都可以(String常量,Integer,Long不能使用)。当一个线程拿到锁之后,其他的线程就只能等待当前线程执行完,
并释放锁之后,才能拿到锁并执行。以此来保证线程的安全。
2,这两种方式我们该用哪一种呢?实际开发中,我们应该用代码块的方式,为什么要加锁,通常都是需要访问共享变量才会加锁,一个方法中并不是所有代码都需要访问共享变量,
其他的业务逻辑是不需要加锁的,所以代码块的方式可以提高程序的性能。
3,synchronized是一种可重入的锁,什么意思呢,就是如果synchronized代码块中又调用了另外一个加锁的方法,本来如果锁没有释放,是不能拿到锁的。但是可重入锁是可以的,系统会自动识别。
synchronized的底层实现:
jdk早期的时候,synchronized的底层实现是重量级的,重量到可能需要到操作系统去申请锁的地步,所以造成synchronized的效率非常低。jdk1.6之后进行了改进,有了锁升级的概念。
当我们访问synchronized的时候,HotSpot的实现是这样的,当第一个线程来访问的时候,先在锁对象的头上markword记录这个线程,实际上只要一个线程来访问的时候,是不会加锁的,
只是记录这个线程ID,此时称之为偏向锁。
偏向锁如果有线程竞争的话,比如我第一个线程还没有释放锁,第二个线程又来了,就会自动升级为自旋锁,自旋锁的实现原理就是,线程会一直转圈等待获取锁,如果转圈十次之后,还没有获取到锁
就自动升级为重量级锁。
所以说从效率方面来讲,CAS(后续文章会讲解)并不是一定就比synchronized锁的效率高,理解synchronized的底层实现,我们就可以得到如下结论:
- 被锁住的代码,执行实际短,线程数量少的情况,用CAS。
- 被锁住的代码,执行时间长,线程数量多的情况,用系统锁(synchronized内部锁和lock显示锁)。
为什么这样说呢,假如我有1000个线程,用CAS自旋,那岂不是有999个线程会一直在旋转等待,这样是非常消耗资源的。
谈谈synchronized的更多相关文章
- Java多线程之二(Synchronized)
常用API method 注释 run() run()方法是我们创建线程时必须要实现的方法,但是实际上该方法只是一个普通方法,直接调用并没有开启线程的作用. start() start()方法作用为使 ...
- java 美团面试常见问题总
一 基础篇 1. System.out.println(3|9)输出什么? 2. 说一下转发(Forward)和重定向(Redirect)的区别 3. 在浏览器中输入url地址到显示主页的过程,整个过 ...
- 关于Javakeywordsynchronized——单例模式的思考
精彩的设计模式盛宴刚刚落下帷幕.三天的时间.真是学习到了非常多.当中,遗留的非常多的问题.今天就谈谈synchronized这个keyword.关于对synchronizedkeyword的思考是从单 ...
- Java程序员备战“金九银十”必备的面试技巧(附携程Java岗面试题)
一.面试前的准备 1.1 如何准备一场面试1.1.1 如何获取大厂面试机会1.1.2 面试必知 ①. 准备介绍自己 ②. 关于着装 ③ .随身带上自己的成绩单和简历 ④. 如果笔试就提前刷一些笔试题 ...
- 【强烈推荐】可能是最适合你的 Java 学习路线和方法
如遇链接无法打开,建议使用 https://github.com/Snailclimb/JavaGuide/blob/master/docs/questions/java-learning-path- ...
- 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...
- Java并发专题
——参考于码农求职小助手公众号 1.并行和并发有什么区别? 1. 并行是指两个或者多个事件在同一时刻发生:而并发是指两个或多个事件在同一时间间隔发生: 2. 并行是在不同实体上的多个事件,并发是在同一 ...
- BATJ都爱问的多线程面试题
# 一 面试中关于 synchronized 关键字的 5 连击 ### 1.1 说一说自己对于 synchronized 关键字的了解 synchronized关键字解决的是多个线程之间访问资源的同 ...
- Java 并发进阶常见面试题总结
声明:本文内容完全来自网络,转自GitHub->JavaGuide(https://github.com/Snailclimb/JavaGuide),致谢 1. synchronize ...
随机推荐
- gitlab介绍
1. GitLab简介 GitLab是一个利用 Ruby on Rails 开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目. GitLab拥有与G ...
- macvlan几种模式
vepa模式:各个子设备直接无法直接通信(可以通过支持端口聚合的交换机通信),可以和外部通信. private模式:和vepa模式类似,各个子设备之间无法通信,即使通过支持端口聚合的交换机也不能. b ...
- 协同开发功能——Github团队协作
最近需要写一个HoloLens开发的简明介绍,其中要测试几个demo.用到github以团队协作,像下面是简单的事件记录. 一.创建项目 1. 2.项目设置 名称 描述description Init ...
- 机器分配----线性dp难题(对于我来说)
题目: 总公司拥有高效设备M台, 准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M <= 15, ...
- lumen 添加配置
app同级目录新建config目录 添加配置文件 bootstrap/app.php里面加载 $app->configure('options');使用 $router->get('/', ...
- selenium 图片懒加载
from selenium import webdriver options = webdriver.ChromeOptions() prefs = {} prefs['profile.managed ...
- 第十二章 LNMP架构之分离数据库
一.课程回顾 1.搭建LNMP环境 1.配置官方源2.yum安装依赖3.yum安装nginx4.配置nginx5.创建用户6.启动并加入开机自启7.上传安装包8.解压安装包9.卸载旧版本PHP10. ...
- JavaScript的9大排序算法详解
一.插入排序 1.算法简介 插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. ...
- Dijkstra算法 python实现
1.Dijkstra算法的基本实现 \(O(n^2)\) 简介: Dijkstra算法是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题.迪杰斯特拉算法主要特点是从起始点开始,采用贪 ...
- Pytest学习(三) - setup和teardown的使用
一.前言 从文章标题可以看出,就是初始化和释放的操作,根据我的java习惯来学习pytest,个人感觉没差太多,理解上也不是很难. 哦,对了,差点跑题了,这个框架是基于Python语言的,在学习的时候 ...