Java多线程面试问题总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/May_3/article/details/82145781

这篇博文总结一些面试之中Java多线程的一些关键问题。每一个问题,会简要介绍,一些问题,下面会附上详细的介绍博文链接,方便小伙伴们更好的学习和交流。谢谢大家。

目录

CAS

  Compare and Swap ,也就是比较和替换。假设有三个操作数:内存值V、旧的预期值A、要修改的值B。当且仅当预期值A和内存值V相同时,才会将内存值修改为B并返回true,否则什么都不做并返回false。
  当然CAS一定要volatile变量配合,由于volatile的可见性,才能保证每次拿到的变量是主内存中最新的值。


AQS

  抽象队列同步器。JUC的核心就是AQS-AbstractQueuedSynchronized。在内部,以一个双向队列维护所有的Entry。例如,在ReetrantLock中,所有等待获取锁的线程都被放在一个Entry中连接成双向队列。
  参考博文: Java并发编程基础—(9)Java中的锁—队列同步器


自旋

  由Synchronized修饰的代码块,在一个线程进入代码块后,其他线程必须在外等待进入阻塞状态。在很大程度上降低了程序运行的效率。如果,Synchronized修饰的代码块运行速度较快,那么可以尝试让其他等待锁的线程在Synchronized做忙循环,也就是自旋。如果做了多次忙循环,仍然没有获得锁,再进入阻塞状态。


volatile关键字

  • 可见性 :对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写。
  • 原子性:对单个volatile变量的读/写具体原子性,但对于Volatile++这样的操作(写+赋值,本质上是两步操作)不具有原子性。

内存语义分析
  volatile关键字能保证可见性的原因是,假设现在有线程A和线程B,线程A对volatile边;1进行修改,然后线程B读一个volatile变量时,JVM会把线程B的本地内存置为无效,接下来去共享内存中读取共享变量。


Synchronized的实现

  Synchronized可以保证同步代码块在某个时间内,只有一个线程进入,其他线程在队列中阻塞,等待。那么在底层是如何实现的呢?
  在底层,对于同步代码块使用了monitorenter(监视器进入)和monitorexit(监视器退出)指令。对于Synchronized修饰的同步方法,使用了ACC_SYNCHRONIZED。本质上,是对一个对象的监视器(monitor)进行获取,而且这个获取的过程是互斥的,在某一时刻只能有一个线程获取到由Synchronized保护的对象监视器。
  只有获得了这个监视器才可以进入同步代码块或者同步方法,未获得的线程被阻塞在同步代码块或者同步方法的入口处,进入BLOCKED(阻塞)状态。


不断更新中。。。。。

猜你喜欢

转载自blog.csdn.net/May_3/article/details/82145781