线程同步方法一:同步代码块

同步代码块

作用

把访问共享资源的核心代码给上锁,以此保证线程安全。

格式

synchronized(同步锁){

访问共享资源的核心代码

}

原理

多个线程在执行这个代码块之前必须竞争获取指定对象的锁。因为互斥访问:同一时间只有一个线程能持有锁并执行同步块内的代码,其他线程会被阻塞,直到锁被释放。

同步锁的条件

唯一性:对于当前同时执行的线程来说,同步锁必须是同一把(同一个对象)。因为如果不是唯一的话,那么就可能多个线程可以同时执行核心代码块,违背了synchronized关键字的原理

锁对象的使用规范

对于实例方法建议使用this作为锁对象

不能随便取一个唯一的对象。因为它会阻止你同时操作两个不同的账户,但是我们只需要阻止同时操作同一个账户。所以我们应该用this作为锁对象。

为什么要用this作为锁对象,因为 synchronized (this) {}这行代码是在public void drawAccount() {}这个方法里的,所以this可以拿到调用drawAccount这个方法的对象。

那么this 就代表了当前对象实例的引用。在实例方法中使用 synchronized (this),意味着锁与当前对象实例绑定。每个对象实例都有自己独立的锁,因此不同实例之间的操作不会互相阻塞。

优势:确保同一实例的线程安全,又可以支持不同实例的并发操作

public class threadDemo1 {
    public static void main(String[] args) {
        //目标:线程同步的方式一:同步代码块
        //1、设计一个账户类,用于创建小明和小红的共同账户(10w元0
        Account acc = new Account("ICBC-001", 100000);

        //2、设计线程类,创建小明和小红两个线程,模拟小明和小红同时去同一个账户取10万
        new DrawThread("小明",acc).start();
        new DrawThread("小红",acc).start();
    }
}




public void drawAccount() {
    //拿到当前线程
    String name = Thread.currentThread().getName();
    synchronized (this) {
        //判断余额是否足够
        if (money >= 100000) {
            System.out.println(name + "取款成功,吐出钞票"+money+"元");
            money -= 100000;
            System.out.println(name + "取款成功,金额剩余"+money+"元");
        } else {
            System.out.println(name + "取款失败,余额不足");
        }
    }
}




public class DrawThread extends Thread {
    private Account acc;
    public DrawThread(String name, Account acc){
        super(name);
        this.acc = acc;
    }

    @Override
    public void run() {
        acc.drawAccount();
    }
}

对于静态方法建议使用字节码(类名.class)对象作为锁对象

唯一性:每个加载到JVM中的类都有一个唯一的 Class 对象。通过使用 类名.class 作为锁,可以确保锁的唯一性。所以无论有多少个该类的实例,所有对该类静态资源的访问都会受到这同一个锁的保护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值