• java并发编程:synchronized同步方法


    非线程安全问题:

    多个线程对同一个对象中的实例变量进行并发访问时发生,产生脏读,读取的数据可能是被更改过的。

    当多个线程同时访问同一个业务对象中没有同步的方法,可能出现非线程安全问题。

    解决办法:

    使用synchronized声明,保证方法只能由获得锁的线程执行。

    在用synchronized声明的方法中,线程进入方法时就获得锁,方法执行完就释放锁。

    (1)对于方法内部的私有变量,不存在非线程安全问题。

    (2)多个线程同时访问同一个对象中的同步方法一定是线程安全的。

    同步synchronized在字节码指令中的原理:

    1、synchronized关键字声明的同步方法:

    使用flag标记ACC_SYN-CHRONIZED,当调用方法时,调用指令会检查方法的ACC_SYNCHRONIZED访问标志。如果设置,执行线程先持有同步锁,然后再执行方法,最后在方法完成时释放锁。

    2、synchronized声明代码块:

    使用monitorenter和monitorexit字节码指令进行同步处理。

    补充:

    同步:按顺序执行业务。

    异步:执行A业务同时执行B业务。

    注意:

    (1)如果线程和业务之间属于一对一的关系,每个线程执行自己所属业务的同步方法,不存在争抢关系,不会出现非线程安全问题。只有多个线程执行相同的业务对象的同步方法时,线程 和业务对象属于多对一的关系,为了避免出现非线程安全问题,使用锁。

    (2)调用synchronized声明的方法是排队进行运行的。

    (3)如果A线程先持有Object对象的lock锁,B线程如果调用object对象中的synchronized方法,需要等待。

    (4)java中,锁就是对象,对象可以映射成锁,哪个线程拿到锁,哪个线程就可以执行这个对象中的synchronized方法

    (5)使用synchronized声明非静态方法,那么锁就是调用方法的对象。

    (6)出现异常,锁自动释放

    (7)通常情况下,一旦持有锁后就不再对锁对象进行更改。

    synchronized锁重入:

    当一个线程得到一个对象锁时,再次请求此对象锁时可以得到对象锁的。

    (1)在synchronized方法/块的内部调用本类的其他synchronized方法/块时,是可以得到锁的。如果得到锁,在没有释放之前可以再次得到锁

    (2)锁重入支持继承。当存在父子类继承关系时,子类是完全可以通过锁重入调用父类的同步方法。

    synchronized同步语句块:

    用synchronized声明方法在某些情况下是有弊端的 。

    例如A线程调用同步方法执行一个长时间的任务,那么B线程等待时间就长。

    可以 用synchronized语句块来解决。

    synchronized代码块是将任意对象作为锁。

    当两个并发线程访问同一个对象Object中的synchronzied代码块时,只有获得锁的线程才能执行代码块。

    (1)不在synchronized代码块中是异步执行。

    (2)synchronized(this)用当前对象作为锁。

    (3)同步代码块放在非同步的syn方法中进行声明,并不能保证调用方法的线程执行同步,

    方法的调用时无序的。

    (4)如果用syn对对象x加锁,那么其他线程执行x对象的同步方法呈现同步效果。

    使用class对象作为锁:

    Class类用于描述类的基本信息,在内存中设计为单例。

    静态同步synchronized方法/synchronized(class)同步块:

    (1)synchronized声明静态方法,锁使用当前静态方法所在类对应的Class类的单例对象。

    (2)synchronzied(class)使用Class类作为锁。

  • 相关阅读:
    Windows系统下安装CouchDB3.3.2教程
    基于javaweb的员工管理系统(前后端分离+java+vue+springboot+ssm+mysql+redis)
    广州华锐互动:办税服务厅税务登记VR仿真体验让税务办理更加灵活高效
    rust重载比较运算符
    TLS及CA证书申请流程
    华为设备配置大型网络WLAN基本业务
    springboot中定时任务cron不生效,fixedRate指定间隔失效,只执行一次的问题
    C++ 之 Visual Studio 搭建 EasyX Graphics Library 图形库环境,并使用EasyX(graphics.h)绘制第一个图形
    【译】.NET 7 中的性能改进(三)
    前端综合面试题【看这一篇就够了】
  • 原文地址:https://blog.csdn.net/m0_52043808/article/details/125902762