,线程的状态。,
,
,用法:,在 JDK 1.6 之前,synchronized 只有传统的锁机制,因此给开发者留下了 synchronized 关键字相比于其他同步机制性能不好的印象。在 JDK 1.6 引入了两种新型锁机制:偏向锁和轻量级锁,它们的引入是为了解决在没有多线程竞争或基本没有竞争的场景下因使用传统锁机制带来的性能开销问题。,锁的升级: 偏向锁->轻量级锁->重量锁,锁的映射关系存在对象头中的。32 位系统上各状态如图所示:,
,当 JVM 启用了偏向锁,那么新创建的对象都是可偏向状态,此时 mark word 里的 thread id 为 0,表示未偏向任何线程,线程在执行同步块之前,JVM 会在线程的栈帧上建立一个 Lock Record。其包括了一个存储对象头中的 mark word 的 Displaced Mark Word 以及一个对象头指针。,
,利用的是 JVM 的监视器(Monitor),java 会为每个 object 对象分配一个 monitor,当某个对象的同步方法(synchronized methods )被多个线程调用时,该对象的 monitor 将负责处理这些访问的并发独占要求。,过程如下:,过程如下:,
,
,如果获取成功:则 state 加 1,并调用 AQS 的父类
AbstractOwnableSynchronizer 的设置独占线程,把当前独占线程设置当前线程。
如果调用失败:则说明,前面已经有线程占用了这个资源,需要等待的线程释放。则把当前线程封装成 node 节点,放入 node 双向链表,之后 Locksupport.pack()堵塞当前线程。假如这个线程堵塞后被唤醒,则继续循环调用 tryAcquire 方法获取资源许可,获取到了,则把自身 node 节点设置为 node 链表的头节点,把之前的头节点去掉。
node 节点的 waitStatus 为 signal,则意味这其 next 节点可以被唤醒。,如果线程释放资源,调用 release 方法,release 方法会调用 tryRelease 方法尝试释放资源,如果释放成功,tryRelease 方法会将 state 减 1,再调用 AQS 的父类
AbstractOwnableSynchronizer 的设置独占线程为 null,再 locksupport.unpack()双向 node 链表的头 node 节点的线程,恢复其执行。,顺序打印 ABC。,
© 版权声明
文章版权归作者所有,未经允许请勿转载。