Java—Synchronized锁

1.Synchronized

是一个关键字,JVM级别的锁。

锁的是对象!!

同时是一个悲观锁、重量级锁。(悲观锁就是老往最坏情况考虑)

隐式加解锁(monitor支持可重入)。

2.使用

1.同步代码块

2.同步方法

区别:锁的粒度不同

【同步代码块】必须传入要锁住的对象 !!!

   public void run() {
        for(int i=0;i<100;i++){
            //线程在外面等
            synchronized (this){
                //为程序上锁
                if(this.ticket >0){
                    System.out.println(Thread.currentThread().getName()+"还剩下"+ticket--+"张");
                }
            }
        }
    }
【同步方法】这个方法同一时间只有一个线程可以进


public synchronized void 方法名(){
	方法体;
}

但是如果方法是对象方法的话,不同的对象调用这个方法,是可以同时进的。

为了解决这个问题,1.可以在方法前加static,使其变为类方法。  2.对这个对象控制唯一性(Class对象)

 

有一个同步队列、一个等待队列。

一般获取锁失败先会CAS自旋一会,如果一直没有释放则是获取失败,加入同步队列,等待获取锁。

wait()后将线程阻塞加入等待队列。

notify()唤醒等待队列中的线程,使其加入同步队列,等待获取锁。

 

 

3.实现原理

对象锁monitor,Synchronized锁通过操作monitor指令,获取锁(monitorenter),释放锁(monitorexit),来自动加减锁。

同一时间只有一个线程能获取对象锁。

通常一个获取锁,包含着多个退出指令。这样是避免异常情况下能正常释放锁。

4.CAS

因为它是一个悲观锁,所以在乐观情况下它的效率十分低。

在JDK1.6引入了CAS(乐观锁策略)来优化这个锁。

CAS:不断尝试策略,总是乐观的认为下一次可以获取到锁。

当获取锁失败时候,不是武断地挂起线程,而是再不断地尝试再次获取。

了解CAS要先了解三个变量:V(实际值)O(预期值)N(新值)

if(V==O){
    V=N; //成功
}else{
    return V;  //失败
}

CAS存在3个问题

1.ABA问题:A先改成1,B在改成0,A再改成1;

解决:加入版本号/名字 1A->0B->1A

2.浪费CPU:因为不断尝试获取锁,会浪费部分CPU完成其操作

解决:自适应自旋

3.不公平:对同步队列中排队等待的线程不公平,因为又可能是自旋的线程先获取到,而等的久的线程却获取不到

解决:Lock公平锁

 

5.JDK1.6优化

无锁、偏向锁、轻量级锁、重量级锁、锁粗话、锁消除

实现原理:

在Java对象的对象头(32位)中,存放有HashCode、分代年龄、锁标记位

锁标记位:分为无锁(0 01)、偏向锁(1 01)、轻量级锁(00)、重量级锁(10)

锁规定只可升级为更重量的锁,不能降级

偏向锁:这把锁总是一个线程在获取

只会在第一次请求时使用CAS

获取:1.看本线程ID和对象头中的线程ID是否相等  2.相等,直接进入。 3.看标识字段是否为1,为0,就把本线程ID存入,为1就开始竞争。

释放:1.出现竞争,将字段设为001  2.将当前对象锁升级为轻量级锁

轻量级锁:这把锁在某一时刻只有一个线程获取

获取:JVM在线程帧中开辟锁记录空间,并复制锁记录存入。使用CAS将对象头中的锁记录更换成指向线程帧的指针。

释放:CAS将锁记录替换回对象头,失败则升级为重量级锁。

重量级锁:这把锁在同一时刻有多个线程获取

JVM会阻塞重量级锁的进程,等待锁释放会被唤醒

在阻塞之前会自旋,询问是否释放,释放则直接获取

 

过多的同步锁会造成死锁,(多个线程都在彼此等待着对方的锁释放)所以注意加锁要适量,加锁勿成环。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值