Giter VIP home page Giter VIP logo

study-synchronized's Introduction

Synchronized

  • 官方解释:同步方法支持一种简单的策略来防止线程干扰和内存一致性错误:如果一个对象对多个线程可见, 则对该对象变量的所有读取或写入都是通过同步方法完成的。

  • 通俗解释:能够保证在同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。

Synchronized的地位

  • Synchronized是Java关键字,被Java语言原生支持

  • 最基本的互斥同步手段

  • 是并发变成中的元老级角色,是并发编程的必学内容

不使用并发手段会有什么后果

  • 代码实战: 两个线程同时a++,最后结果会比预计的少

  • 原因: a++,它看上去只是一个操作,实际上包含了三个动作:

    • 读取a
    • 将a+1
    • 将a的值写到内存中

Synchronized的用法

  • 对象锁: 包括方法锁(默认锁对象为this当前实例对象)和同步代码块锁(自己指定锁对象)

      `SynchronizedObjectCodeBlock2` `SynchronizedObjectMethod3`
    
  • 类锁: 指synchronized修饰静态的方法或指定锁为Class对象

    • 概念:Java类可能又很多对象,但只有一个Class对象
      • 本质:所以所谓的类锁,不过是Class对象的锁而已。
      • 用法和效果:类锁只能在同一时刻被一个对象拥有。
    • 形式1:synchronized加在static方法上
    • 形式2:synchronized(*.class)代码块

多线程访问同步方法的7中情况(面试常考)

  • 1.两个线程同时访问一个对象的同步方法

  • 2.两个线程访问的是两个对象的同步方法

  • 3.两个线程访问的是synchronized的静态方法

  • 4.同时访问同步方法和非同步方法 SynchronizedYesAndNo6

  • 5.访问同一对象的不同的普通同步方法 SynchronizedYesAndNo7

  • 6.同时访问静态synchronized和非静态

  • 7.方法抛异常后,会释放锁。

总结

  • 1.一把锁只能同时被一个线程获取,没有拿到锁的线程必须等待(对应第1 5 情况)

  • 2.每个示例都对应有自己的一把锁,不同示例之间互不影响;例外: 锁对象是*.class以及synchronized修饰的是static方法的时候,所有的对象公用同一把类锁(对应第2 3 4 6种情况)

  • 3.无论是方法正常秩序完毕或者方法抛出异常,都会释放锁(对应第7种情况)

Synchronized性质

  • 可重入

    • 什么是可重入: 指的是统一线程的外层函数获得锁之后,内层函数可以直接再次获取该锁

    • 好处:避免死锁 提升封装性

    • 粒度:线程而非调用(用3种情况来说明和pthread的区别)

      • 情况1:证明同一个方法是可重入的
      • 情况2:证明可重入不要求是同一个方法
      • 情况3:证明可重入不要求是同一个类中的
  • 不可中断

    • 什么事不可中断:一旦这个锁被别人获得了,如果我还想获得,我只能选择等待或阻塞,直到别的线程释放这个锁。如果别人永远不释放锁,那么我只能永远的等下去。 相比之下,未来会介绍Lock类,可以拥有中断的能力,第一点,如果我觉得我等的时间太长了,有权中断现在已经获取到锁的线程的执行 第二点,如果我觉我等待的时间太长了不想再登了,也可以退出。

Synichronized原理

  • 加锁和释放锁的原理

    • 现象:
    • 获取和释放锁的时机:内置锁
    • 等价代码
    • 深入JVM看字节码:反编译 monitor的指令
      • 概况
      • 反编译 javac Decompliation14.java javap -verbose Decompliation14.class
      • Monditorenter和Monditorexit指令
  • 可重入原理:加锁次数计数器

    • JVM负责跟踪对象被加锁的次数
    • 线程第一次给对象加锁的时候,计数变为1.每当这个相同的线程在此对象上再次获得锁时,计数会增加
    • 每当任务离开时,计数递减,当计数为0的时候,锁被完全释放
  • 可见性原理:Java内存模型

缺陷

  • 效率低:锁的释放情况少,试图获得锁时不能设定超时,不能中断一个正在试图获得锁的线程
  • 不够灵活(读写锁更灵活):加锁和释放的时机单一,每个锁仅有单一的条件(某个对象) 可能是不够的
  • 无法知道是否成功获取到锁

常见面试问题

  • 1.使用注意点:锁对象不能为空,作用于不宜过大,避免死锁。

  • 2.如何选择Lock和Synchronized关键字?

    有现成的工具类,优先使用工具类,没有则选择Synchronized,避免少写代码,如果需求要定义自定义的加解锁规则,则选择Lock

  • 3.多线程访问同步方法的各种具体情况

study-synchronized's People

Contributors

niezhiliang avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.