多线程20-同步方法及同步块

同步方法

我们通过private关键字来保证数据对象只能被方法访问,针对此提出synchronized关键字,包括两种用法:synchronized方法和synchronized块

//同步方法
public synchronized void method(int args){}

synchronized方法控制对“对象“的访问,每个对象一把锁,每个synchronized方法都必须获得调用该方法的对象的锁才能执行,否则线程会阻塞。方法一旦执行,独占该锁,直到该方法返回才释放锁,后面被阻塞的线程才能获得这个锁,继续执行

缺陷:若将一个大的方法申明为synchronized将会影响效率

同步块

synchronized(Obj){} 锁住增删改的对象

Obj称之为同步监视器

  • Obj可以是任何对象,但是推荐使用共享资源作为同步监视器
  • 同步方法中无需指定同步监视器,this就是,即这个对象本身,或者是class

同步监视器的执行过程:

  1. 第一个线程访问,锁定同步监视器,执行其中代码
  2. 第二个线程访问,发现同步监视器被锁定,无法访问
  3. 第一个线程访问完毕,解锁同步监视器
  4. 第二个线程访问,发现同步监视器没有锁,然后锁定并访问

修改上一节的不安全案例

//synchronized同步方法,锁的是this
    private synchronized void buy(){
        
输出:我拿到了第10张票
我拿到了第9张票
我拿到了第8张票
他拿到了第7张票
你拿到了第6张票
你拿到了第5张票
他拿到了第4张票
他拿到了第3张票
他拿到了第2张票
我拿到了第1张票
//取钱
    //synchronized 默认锁的是this
    public void run(){
        
        //同步块
        synchronized (account){//锁的对象就是变化的量,需要增删改的对象
            //判断有没有钱
            if(account.money-drawingMoney<0){
                System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
                return;
            }

            //sleep放大问题的发生性
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //卡内余额=余额-你取的钱
            account.money=account.money-drawingMoney;
            //你手里的钱
            nowMoney = nowMoney+drawingMoney;

            System.out.println(account.name+"余额为"+account.money);
            //Thread.currentThread().getName()=this.getName()
            System.out.println(this.getName()+"手里的钱"+nowMoney);
        }  
        }
输出:旅游基金余额为50
你手里的钱50
他钱不够,取不了       
 new Thread(()->{
                synchronized(list){ list.add(Thread.currentThread().getName());}
            }).start();
输出:10000
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值