synchronized的实现原理与应用


写一个关于卖票的方法 - - 多线程操纵数据

public class TestSync {
public static void main(String[] args) throws InterruptedException {
        MaiPiao piao = new MaiPiao();
        Thread [] threads = new Thread[10];//10个窗口
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new Window(piao));
        }//对线程进行循环 , 把买的票传给他
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }//让线程去启动
        Thread.sleep(5000); //让主线程休5s 让那10个线程跑完
        piao.tikectCheck(); //检查一下还有没有票
    }
}
//窗口负责卖票
class Window implements Runnable{
    //我持有一个票
    private MaiPiao piao;
    public Window(MaiPiao piao) {
        this.piao = piao;
    }
    @Override
    public void run() {
        for (int i = 2; i < 100; i++) {
            piao.sold();
        }
    }
}
class MaiPiao{
    private int tikect=1000;
    public void sold(){
        tikect--;
    }
    public void tikectCheck(){
        System.out.println(tikect);
    }

}

预期结果是20 , ,但是有些运行结果并不是20,这是一个不安全的线程
如果在 public void sold(){ }中加一个synchronized ,private int tikect=1000;的数值变大一点, 输出结果还是20
synchronize是一个重量级锁
先来看下利用synchronized实现同步的基础:Java中的每一个对象都可以作为锁。具体表现 为以下3种形式:
①对于普通同步方法,锁是当前实例对象。
②对于静态同步方法,锁是当前类的Class对象。
③对于同步方法块,锁是Synchonized括号里配置的对象。
②的使用
在这里插入图片描述
在这里插入图片描述
改成静态的,相互之间是共享的 ;;; 输出结果是20
10个线程每个都持有一个票这个对象,对象只供自己的锁使用,又回到了开始的状态
③ 的使用
在这里插入图片描述

一、对象头

synchronized用的锁是存在Java对象头里的。如果对象是数组类型,则虚拟机用3个字宽 (Word)存储对象头,如果对象是非数组类型,则用2字宽存储对象头。在32位虚拟机中,1字宽 等于4字节,即32bit,在64位虚拟机中,1字宽就是8位.64bit

二、锁的升级和对比

竞争: 十个锁抢一个线程就是竞争
锁只能升级不能降级

1.偏向锁

当一个线程访问同步代码块并且获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的id
在对象上刻上自己的id,下次在访问的时候直接去比较就行了
在这里插入图片描述
等到竞争才会释放锁的机制

2.轻量级锁

CAS操作,比较并交换,比较成功交换,不成功不交换,…
轻量级解锁时,会使用原子的CAS操作将Displaced Mark Word替换回到对象头,如果成 功,则表示没有竞争发生。如果失败,表示当前锁存在竞争,锁就会膨胀成重量级锁。图2-2是 两个线程同时争夺锁,导致锁膨胀的流程图。
在这里插入图片描述
虽然在竞争,由于持有的时间不是很长,线程2有所谓的耐心,在耐心耗完之前获得了锁,便不会膨胀成轻量级锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小冻梨♬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值