美文网首页
Java并发

Java并发

作者: 蜡笔没了小新_e8c0 | 来源:发表于2019-08-19 00:09 被阅读0次

    1. 八个操作

    • lock(锁定)
    • unlock(解锁)
    • read(读取):作用于主内存的变量,把一个变量的值从主内存传输到线程的工作内存中,以便后续的load动作使用。
    • load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。
    • use(使用):相当于get
    • assign(赋值):相当于set
    • store(存储):作用与工作内存的变量,它把工作内存中一个变量的值传送到主内存中,以便后续的write操作使用。
    • write(写入):作用与主内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。

    2. 内存模型八种规则

    • 不允许read和load、store和write操作之一单独出现,即不允许一个变量从主存读取了但工作内存不接受,或者从工作内存发起回写了但主内存不接受的情况出现。
    • 不允许一个线程丢弃它最近的assign操作,即变量在工作内存中改变了之后必须把该变化同步回主内存。
    • 不允许一个线程无原因(没有发生过任何assign操作)地把操作从线程的工作内存同步回主内存中。
    • 一个新的变量只能在主内存中“诞生”,不允许在工作内存中直接使用一个未被初始化(load或assign)的变量,也就是对一个变量实施use和store操作之前,必须先执行过了load和assign操作。
    • 一个变量在同一个只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。(可重入)
    • 如果对一个变量执行lock操作,将会清空工作内存中该变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作初始化变量的值。
    • 如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作;也不允许去unlock一个被其他线程锁定住的变量。
    • 对一个变量执行unlock操作之前,必须先把该变量同步回主内存中(执行store和write操作)。

    3.lock是怎么确保线程安全的?

    根据内存模型的规则,当执行lock时,会把工作内存中的变量清空,重新执行read和load操作,确保工作内存中的变量和主内存一致。执行unlock时,会把工作内存的值通过store和write操作同步会主内存。

    4.volatile可以保证原子性吗?

    不能,volatile的可见性只能保证在获取值的时候该值是最新的,可是有可能在对值进行操作时,别的线程对该值进行了修改操作。

    5.volatile适用场景?

    • 运算结果不依赖于变量的当前值,或者能够确保只有单一的线程修改变量的值。
    • 变量不需要与其他的状态变量共同参与不变约束。

    6.volatile如何保证可见性?

    使用变量前都必须从主内存中刷新最新的值,修改变量后必须立即同步会主内存中。

    7.volatile如何实现禁止指令重排序?

    因为volatile规则要求如果某个线程先对某个变量执行了use或assign操作,那么该线程也必须先执行read或write操作。(这条规则要求volatile修饰的变量不会被指令重排序优化,保证代码的执行顺序与程序的顺序相同)。

    8.synchronized如果保证原子性,可见性,有序性?

    • 原子性:通过monitorenter和monitorexit字节码指令,也即lock和unlock操作。
    • 可见性:是由“对一个变量执行unlock操作之前,必须先把此变量同步会主内存中”这条规则获取的。
    • 有序性:是由“一个变量在同一个时刻只允许一个线程对其进行lock操作”这条规则获得的。

    9.先行发生原则

    • 程序次序原则:在一个线程内,按照程序代码顺序,书写在前面的操作先行发生于书写在后面的操作。
    • 管程锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作。
    • valatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作。
    • 线程启动规则:Thread对象的start方法先行发生于此线程的每一个动作。
    • 线程终止规则:线程中的所有操作都先行发生于对此线程的终止检测。
    • 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测到是否有中断发生。
    • 对象终结规则:一个对象的初始化完成先行发生于它的finalize()方法的开始。
    • 传递性:如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。

    10.线程安全的定义?

    当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象就是线程安全的。

    11.ReentrantLock和Synchronized区别?

    • 等待可中断
    • 公平锁
    • 绑定多个条件(condition)
    • 释放锁机制

    相关文章

      网友评论

          本文标题:Java并发

          本文链接:https://www.haomeiwen.com/subject/jagrsctx.html