每日十题八股-2024年12月9日

1.blocked和waiting有啥区别
2.wait 状态下的线程如何进行恢复到 running 状态?
3.notify 和 notifyAll 的区别?
4.notify 选择哪个线程?
5.怎么保证多线程安全?
6.Java中有哪些常用的锁,在什么场景下使用?
7.怎么在实践中用锁的?
8.synchronized和reentrantlock区别?
9.怎么理解可重入锁?
10.synchronized 支持重入吗?如何实现的?
11.syncronized锁升级的过程讲一下

1.blocked和waiting有啥区别?

触发和唤醒机制不同。blocked是被动的,即当要尝试进入一个线程安全的块时,尝试获取锁失败,则会被阻塞直到锁释放。而waiting是主动的,显式地调用wait,join等方法,等到其他线程执行某些操作后,显式调用notify等方法才能被唤醒。一个线程的waiting是不消耗cpu资源的。

2.wait 状态下的线程如何进行恢复到 running 状态?

等待的线程被其他线程对象唤醒,notify()和notifyAll()。
执行了 LockSupport.park() 方法进入了Waiting 状态,那么解锁的时候会执行LockSupport.unpark(Thread)。

3.notify 和 notifyAll 的区别?

同样是唤醒等待的线程,同样最多只有一个线程能获得锁,同样不能控制哪个线程获得锁。
notify是唤醒一个线程,如果该线程没有显示notify的话,其他线程就永远没有人去唤醒了。
notifyall:所有线程退出wait的状态,开始竞争锁,但只有一个线程能抢到,这个线程执行完后,其他线程又会有一个幸运儿脱颖而出得到锁。

4.notify 选择哪个线程?

notify在源码的注释中说到notify选择唤醒的线程是任意的,但是依赖于具体实现的jvm。
JVM有很多实现,比较流行的就是hotspot,hotspot对notofy()的实现并不是我们以为的随机唤醒,,而是“先进先出”的顺序唤醒。

5.怎么保证多线程安全?

synchronized
volatile
Lock接口和ReentrantLock类
原子类
线程局部变量 ThreadLocal
并发集合:ConcurrentHashMap等
JUC工具类,负责线程之间的同步和协助。

6.Java中有哪些常用的锁,在什么场景下使用?

内置锁(synchronized):加锁时有无锁、偏向锁、轻量级锁和重量级锁几个级别。
ReentrantLock:如可中断的锁等待、定时锁等待、公平锁选项。
读写锁(ReadWriteLock):接口定义了一种锁,允许多个读取者同时访问共享资源,但只允许一个写入者。
乐观锁和悲观锁:悲观synchronized,和ReentrantLock。乐观CAS。
自旋锁:自旋锁是一种锁机制,线程在等待锁时会持续循环检查锁是否可用,而不是放弃CPU并阻塞。

7.怎么在实践中用锁的?

synchronized:直接加在方法或代码块上。
Lock接口的实现类:类内声明 private Lock lock = new ReentrantLock();然后

		lock.lock();
        try {
        count++;
        } finally {
        lock.unlock();
        }

ReadWriteLock接口:readLock.lock(); writeLock.lock();

8.synchronized和reentrantlock区别?

synchronized是Java提供的原子性内置锁,这种内置的并且使用者看不到的锁也被称为监视器锁,在编译之后在同步的代码块前后加上monitorenter(锁的计数器+1)和monitorexit(锁的计数器-1)字节码指令。线程和操作系统原生线程是一一对应的,线程被阻塞或者唤醒时时会从用户态切换到内核态。synchronized适用于简单同步需求和不需要额外锁功能的场景。

ReentrantLock 的底层实现主要依赖于 AbstractQueuedSynchronizer(AQS)这个抽象类。AQS 是一个提供了基本同步机制的框架,其中包括了队列、状态值等。ReentrantLock 在 AQS 的基础上通过内部类 Sync 来实现具体的锁操作。可中断性,设置超时时间,公平锁和非公平锁,多个条件变量,可重入性。ReentrantLock适用于需要更高级锁功能、性能优化或复杂同步逻辑的情况。
在这里插入图片描述

9.怎么理解可重入锁?

可重入锁是指同一个线程在获取了锁之后,可以再次重复获取该锁而不会造成死锁或其他问题。当一个线程持有锁时,如果再次尝试获取该锁,就会成功获取而不会被阻塞。
ReentrantLock是基于线程持有锁的计数器。
当一个线程第一次获取锁时,计数器会加1,表示该线程持有了锁。在此之后,如果同一个线程再次获取锁,计数器会再次加1。每次线程成功获取锁时,都会将计数器加1。当线程释放锁时,计数器会相应地减1。只有当计数器减到0时,锁才会完全释放,其他线程才有机会获取锁。

10.synchronized 支持重入吗?如何实现的?

synchronized是基于原子性的内部锁机制,是可重入的。
synchronized底层是利用计算机系统mutex Lock实现的。每一个可重入锁都会关联一个线程ID和一个锁状态status。
在这里插入图片描述

11.syncronized锁升级的过程讲一下?

无锁->偏向锁->轻量级锁->重量级锁。
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值