• 线程同步


    1:线程为什么要同步?

        在多线程的情况下,容易造成数据的安全问题。比如取钱操作,涉及到金钱方面的,强烈建议使用线程同步。

        线程同步主要有两种方式,一种是synchronized(同步监视器),一个是lock锁。

    synchronized

    synchronized关键字的同步方式:

    (1)同步代码块(实例代码块)
        obj就是同步监视器;代码含义:线程开始执行同步代码块之前,必须先获取同步监视器的锁定。    “加锁——修改——释放锁”

    (2)同步方法(普通同步方法,静态同步方法)
        有关键字synchronized修饰的就是同步方法。  

    1. 对于普通方法的同步方法:无需显示指定同步监视器,同步方法的同步监视器就是this,也就是调用该方法的对象。  
    2. 如果是静态方法:那默认监视器就是当前类。

      同一个类的多个对象作为线程target,访问同一资源可以用当前类作为同步监视器
      同一个对象作为多个线程target,访问同一资源可以用当前对象(this)作为同步监视器。
    注意:synchronized关键字可以修饰方法,可以修饰代码块,但不能修饰构造器,成员变量。

    同步锁(Lock)

        Lock、ReadWriteLock是jdk 1.5 提供的两个接口;ReentrantLock(可重入锁)是Lock接口的实现。ReentrantReadWriteLock是ReadWriteLock的实现。
    下图是ReentrantLock和ReentrantReadWriteLock的类图:


    ReentrantLock.png


    ReentrantReadWriteLock.png
       
    在线程安全中常使用的是ReentrantLock(可重入锁)

        通常使用代码格式:
       

    使用Lock与使用同步方法有点类似。只是使用Lock时,显式使用Lock对象作为同步锁。 必须显式调用unlock()释放同步锁。
    而使用同步方法时是隐式的使用当前对象作为同步监视器。   

    2:释放同步监视器的锁定的情况

    (1)当前线程的同步代码块、同步方法执行结束,当前线程即释放同步监视器。
    (2)当前线程的同步代码块、同步方法执行遇到break,return终止了该代码块、方法的执行。
    (3)当前线程的同步代码块、同步方法执行遇到异常,导致该代码块、方法异常终止。
    (4)当前线程的同步代码块、同步方法执行时碰到同步监视器的wait()方法,则当前线程暂停,并释放同步监视器。

    3:线程不会释放同步监视器的情况:    

    (1)线程执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yield()方法来暂停当前线程的执行,当前线程并不会释放同步监听器,但是会让出当前cpu执行权限。
    (2)程序执行同步代码块或同步方法时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放同步监视器。(这就是suspend方法容易造成死锁的原因,你这个线程都抱着同步监视器“挂起”了,那我其它需要这个同步监视器的线程该怎么执行?如果该线程一直不被唤醒,那不就是死锁了嘛......

    4:死锁

        概念:当两个线程互相等待对方释放同步监视器时就会发生死锁。

  • 相关阅读:
    logging模块-logging.basicConfig、logger.setLevel、handler.setLevel优先级
    Python标准模块--logging(转载)
    第三节,入门知识和windows系统安装python环境
    第二节windows系统下Xshell 5软件远程访问虚拟机 Linux系统
    第一节windows系统安装虚拟机VMware 软件
    数学数列
    java String
    linux eclipse 报错过时的方法
    java.util.Random 类
    java uitl
  • 原文地址:https://www.cnblogs.com/xm970829/p/12980987.html
Copyright © 2020-2023  润新知