为什么要用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的更多相关文章

  1. Java多线程之二(Synchronized)

    常用API method 注释 run() run()方法是我们创建线程时必须要实现的方法,但是实际上该方法只是一个普通方法,直接调用并没有开启线程的作用. start() start()方法作用为使 ...

  2. java 美团面试常见问题总

    一 基础篇 1. System.out.println(3|9)输出什么? 2. 说一下转发(Forward)和重定向(Redirect)的区别 3. 在浏览器中输入url地址到显示主页的过程,整个过 ...

  3. 关于Javakeywordsynchronized——单例模式的思考

    精彩的设计模式盛宴刚刚落下帷幕.三天的时间.真是学习到了非常多.当中,遗留的非常多的问题.今天就谈谈synchronized这个keyword.关于对synchronizedkeyword的思考是从单 ...

  4. Java程序员备战“金九银十”必备的面试技巧(附携程Java岗面试题)

    一.面试前的准备 1.1 如何准备一场面试1.1.1 如何获取大厂面试机会1.1.2 面试必知 ①. 准备介绍自己 ②. 关于着装 ③ .随身带上自己的成绩单和简历 ④. 如果笔试就提前刷一些笔试题 ...

  5. 【强烈推荐】可能是最适合你的 Java 学习路线和方法

    如遇链接无法打开,建议使用 https://github.com/Snailclimb/JavaGuide/blob/master/docs/questions/java-learning-path- ...

  6. 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!

    本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...

  7. Java并发专题

    ——参考于码农求职小助手公众号 1.并行和并发有什么区别? 1. 并行是指两个或者多个事件在同一时刻发生:而并发是指两个或多个事件在同一时间间隔发生: 2. 并行是在不同实体上的多个事件,并发是在同一 ...

  8. BATJ都爱问的多线程面试题

    # 一 面试中关于 synchronized 关键字的 5 连击 ### 1.1 说一说自己对于 synchronized 关键字的了解 synchronized关键字解决的是多个线程之间访问资源的同 ...

  9. Java 并发进阶常见面试题总结

    声明:本文内容完全来自网络,转自GitHub->JavaGuide(https://github.com/Snailclimb/JavaGuide),致谢      1. synchronize ...

随机推荐

  1. 安装 Windows 10 系统时分区选择 MBR 还是 GUID?

    一.MBR 和 GUID 的概述 MBR 分区表 MBR:Master Boot Record,即硬盘主引导记录分区表,指支持容量在2.1TB以下的硬盘,超过2.1TB的硬盘只能管理2.1TB,最多只 ...

  2. Python数据类型---数值类型

    一.整数(Integer)简称Int,又称整型,由正整数.负整数.0构成,不包括小数,分数. a,b=1,2 #一种赋值方法,此时a=1,b=2 print(a+b) #加法 3 print(a-b) ...

  3. Spring Boot 系列:日志动态配置详解

    世界上最快的捷径,就是脚踏实地,本文已收录架构技术专栏关注这个喜欢分享的地方. 开源项目: 分布式监控(Gitee GVP最有价值开源项目 ):https://gitee.com/sanjianket ...

  4. Verilog基础入门——简单的语句块编写(一)

    [题干] [代码] module top_module ( input in, output out ); assign out = ~in; endmodule 简单的实现一个非门

  5. selenium登录163邮箱,得到cookie,requests后续请求

    1.场景 很多时候登录操作是比较复杂的,因为存在各种反爆破操作,以及为了安全性提交数据都会存在加密.如果要完全模拟代码去实现登录操作是比较复杂,并且该网站后续更新了登录安全相关功能,那么登录的模拟操作 ...

  6. .NET Core+MongoDB集群搭建与实战

    目录 安装 MongoDB apt 直接安装(方法1) apt 仓库安装(方法2) 方法1.2启动 MongoDB 通过二进制包安装(方法3) 安装依赖 deb 安装 MongoDB tgz 安装 M ...

  7. File、Blob、ArrayBuffer等文件类的对象有什么区别和联系

    前言 在前端中处理文件时会经常遇到File.Blob.ArrayBuffer以及相关的处理方法或方式如FileReader.FormData等等这些名词,对于这些常见而又不常见的名词,我相信大多数人对 ...

  8. 对于某东平台XX娃娃的用户体验进行(严肃、限速)数据分析

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理 本次的爬取目标是某东的一个商品,但从来没有用过,所以本人很好奇.我们就采集这 ...

  9. Helium文档1-WebUI自动化-环境准备与入门

    前言 Helium 是一款 Web 端自动化开源框架,全称是:Selenium-Python-Helium,从名字上就可以看出,Helium 似乎和 Selenium 息息相关,基于Selenium的 ...

  10. Jmeter入门(6)- 参数化

    一.什么是参数化 为什么要参数化? 在发送大量的请求时,键对值是写死的,每次请求都需要去修改,无法实现快速添加的需求.想要快速实现该需求,就需要用到参数化. 什么是参数化? 根据需求动态获取数据并进行 ...