Java从入门到放弃31---多线程并发问题/线程同步/Synchronized关键字/同步方法/同步块

Java从入门到放弃31—多线程并发问题/线程同步/Synchronized关键字/同步方法/同步块

01 并发问题

  • 同一个对象被多个线程同时操作,每个线程在自己的工作内存交互,内存控制不当会造成数据不一致。
  • 举例:上万人同时抢100张票,线上线下同时取一张银行卡上的钱,不安全的集合问题。
  • 解决方案:
    • 加入休眠是为了放大问题的发生性,便于发现问题。
    • 锁机制(队列+锁):由于同一线程的多个进程共享同一块存储空间,在带来方便的同时,也带来了访问的冲突问题,为了保护数据在方法中被访问时的正确性,在访问时加入锁机制(Synchronized)
    • 采用JUC库并发编程,如保证线程安全的一些类:CopyOnWriterArrayList等。

02 线程同步

  • 处理多线程并发问题时 , 多个线程访问同一个对象 , 并且某些线程还想修改这个对象 . 这时候我们就需要线程同步 . 线程同步其实就是一种等待机制 , 多个需要同时访问此对象的线程进入这个对象的等待池形成队列, 等待前面线程使用完毕 , 下一个线程再使用。

  • 由于同一进程的多个线程共享同一块存储空间 , 在带来方便的同时,也带来了访问冲突问题 , 为了保证数据在方法中被访问时的正确性 , 在访问时加入锁机制synchronized , 当一个线程获得对象的排它锁 , 独占资源 , 其他线程必须等待 ,使用后释放锁即可。

  • 弊端:1.一个线程持有锁会导致其他所有需要此锁的线程挂起 。

    ​ 2.在多线程竞争下 , 加锁 , 释放锁会导致比较多的上下文切换和调度延时,引起性能问题。

    ​ 3.如果一个优先级高的线程等待一个优先级低的线程释放锁 会导致优先级倒置 , 引起性能问题。


03 Synchronized关键字

(1)同步方法

  • 同步方法 : public synchronized void method(int args) {}
    
  • 如果一个方法用Synchronized关键字声明,那么对象的锁将保护整个方法。也就是说,要调用该方法,线程必须获得内部的对象锁。每个对象对应一把锁 , 每个synchronized方法都必须获得调用该方法的对象的锁才能执行 , 否则线程会阻塞 ,方法一旦执行 , 就独占该锁 , 直到该方法返回才释放锁 , 后面被阻塞的线程才能获得这个锁 , 继续执行。

  • 采用同步方法的弊端:若将一个较大的方法申明为synchronized 将会严重影响效率。

  • 注:方法里面需要修改的内容才需要锁,锁的作用域太大,会导致资源浪费,严重影响效率。


(2)同步块

  • 同步块 : synchronized (Obj ) { }
    
  • Obj被称之为同步监视器。

  • 监视器的特性:

    • 监视器是只包含私有域的类。
    • 每个监视器类的对象有一个相关的锁
    • 使用该锁对所有的方法进行加锁。
    • 该锁可以有任意多个相关条件。
  • 同步监视器的执行过程:

    • 第一个线程访问 , 锁定同步监视器 , 执行其中代码。
    • 第二个线程访问 , 发现同步监视器被锁定 , 无法访问 。
    • 第一个线程访问完毕 , 解锁同步监视器 。
    • 第二个线程访问, 发现同步监视器没有锁 , 然后锁定并访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值