用洗衣机实例秒懂 Java synchronized:从原理到三种用法详解

🌰 场景:全家共用一台洗衣机(共享资源)

假设你家有一台洗衣机,你和你爸妈三个人都想用它洗衣服(相当于3个线程)。
但洗衣机一次只能洗一家人的衣服(共享资源一次只能被一个“线程”使用),这时候就需要“排队”,不然会乱套。

没有 synchronized 的情况:

你刚把衣服放进洗衣机,按下“开始”按钮,还没等关门,你爸突然按了“暂停”想放他的衣服,你妈同时按了“脱水”……
结果:洗衣机可能报错,衣服洗不干净(数据混乱)。

synchronized 的情况:

洗衣机自带一个“门锁”功能:当一个人开始使用时,会自动锁门,其他人必须等里面的人用完、开门后才能用

  • 你打开洗衣机,放衣服 → 关门并上锁(获取锁)→ 开始洗衣服(执行同步代码)。
  • 你爸和你妈看到门锁着,只能在门口等着(阻塞)。
  • 你洗完后,开门解锁(释放锁),下一个人才能用。

🚪 synchronized 的核心:给资源加一把“互斥锁”

它的作用就是:保证同一时间只有一个线程能“进入”被它保护的代码块(或方法),其他线程必须排队等待。就像上厕所时锁门,别人只能等你出来。

三种常见用法,继续用洗衣机举例:

1. 锁整个方法(实例方法)
public class Washer {
    // 把整个方法变成“带锁的房间”
    public synchronized void wash() { 
        // 洗你的衣服(操作共享资源)
    }
}
  • 相当于:洗衣机的门就是锁,调用 wash() 方法时自动锁门,方法结束后自动开门。
  • 多个线程调用同一个 Washer 实例的 wash() 时,必须排队。
2. 锁静态方法(类级别的锁)

如果洗衣机是“共享设备”(比如小区的公共洗衣机,所有住户共用),这时候锁的是整个“洗衣机类”,而不是某个实例:

public class PublicWasher {
    // 静态方法,锁的是 PublicWasher 这个类(所有实例共享一把锁)
    public static synchronized void wash() { 
        // 洗公共衣服
    }
}
  • 相当于:不管多少台公共洗衣机,只要有一个住户在用,其他住户都得等(因为锁在“公共洗衣机”这个类别上)。
3. 锁代码块(精确控制锁的范围)

如果你只想给“脱水”环节加锁(比如脱水时不能开门),而不是整个洗衣过程:

public class Washer {
    private Object脱水锁 = new Object(); // 自定义一个“锁对象”

    public void wash() {
        // 洗、漂、脱水中,只有脱水需要加锁
        synchronized (脱水锁) { // 给这段代码加锁
            执行脱水程序();
        }
        // 其他步骤不用等,可以并行
    }
}
  • 相当于:只有脱水时锁门,洗衣服时门可以开(其他线程可以做别的事),更灵活。

❓ 为什么需要 synchronized?举个程序员能懂的例子

假设两个线程同时给一个账户转账(共享变量 balance):

int balance = 100; // 初始余额

// 线程A:存50元
balance = balance + 50; 

// 线程B:取30元
balance = balance - 30;

如果没有 synchronized,可能出现:

  1. 线程A刚读取到 balance=100,还没加50,就被线程B打断。
  2. 线程B读取到 balance=100,算出70并写入。
  3. 线程A继续执行,算出150并写入。
    最终余额变成150(正确应该是120),数据出错!

加锁后:

synchronized (账户) { // 锁定账户对象
    balance = balance + 50; // 线程A执行完,释放锁
}
// 线程B才能进来执行
synchronized (账户) {
    balance = balance - 30;
}

保证每次只有一个线程操作 balance,结果就正确了。

✨ 总结

synchronized 就像一把“独占锁”:

  • 作用:确保共享资源在同一时间只能被一个线程使用,避免混乱。
  • 效果:排队执行,先到先得,用完释放。
  • 场景:多个线程操作同一个“东西”(比如变量、文件、数据库)时,必须用它来保证数据安全。

记住:它的核心就是“互斥”,就像你用洗衣机时锁门,别人只能等你用完~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值