多线程
synchronized关键字的底层原理?
❒ Synchronized【对象锁】采用互斥的方式让同一时刻至多只有一个线程能持有【对象锁】,其它线程再想获取这个【对象锁】时就会阻塞住,他是可重入锁(准许中途去执行别的逻辑,执行完毕后继续回来执行当前逻辑)。
基本使用回顾
public class TicketDemo {
static Object lock = new Object();
int ticketNum = 10;
// 模拟获取票
public void getTicket(){
synchronized (lock){
if (ticketNum <= 0){
return;
}
System.out.printin(Thread.currentThread().getName()+"抢到一张票,剩余:" + ticketNum);
// 非原子性操作ticketNum
ticketNum--;
}
// 模拟20个人再抢票
public static void main(String[] args) {
TicketDemo ticketDemo = new TicketDemo();
for (int i = 0; i< 20; i++){
new Thread(()->{ticketDemo.getTicket();}).start();
}
}
}
❒ Monitor 被翻译为监视器,是由jvm提供,c++语言实现,Monitor结构如下:
✔ Owner:存储当前获取锁的线程的,只能有一个线程可以获取
✔ EntryList:关联没有抢到锁的线程,处于Blocked状态的线程
✔ WaitSet:关联调用了wait方法的线程,处于Waiting状态的线程
对于每一个Java对象都可以绑定一个Monitor对象(锁),当多个线程来执行被synchronized修饰的同步代码块时,根据JDK的调度机制会选取其中一个线程来作为该对象绑定的Monitor对象的拥有者(Owner),并且一个Monitor对象只能有一个锁主人(Owner),然后该线程便获得了执行该同步代码块的权利,而对于那些没有被选中的线程则会放入一个等待队列(EntryList)中进行等待,只有当前线程完成工作后才会更新调度规则选出新的Owner。
❒ synchronized关键字的底层原理 以上关于synchronized的讲解是属于在代码层次上的原理,关于锁还有一部分很重要的就是锁的策略,尤其对于synchronized来说,她有以下的一些特性: 1. 开始时是乐观锁, 如果锁冲突频繁, 就转换为悲观锁. 2. 开始是轻量级锁实现, 如果锁被持有的时间较长, 就转换成重量级锁. 3. 实现轻量级锁的时候大概率用到的自旋锁策略 4. 是一种不公平锁 5. 是一种可重入锁 6. 不是读写锁