加锁,把共享资源进行上锁,每次只能一个线程进入访问完毕以后解锁,然后其他线程才能进来。
**作用:**把出现线程安全问题的核心代码给上锁。
**原理:**每次只能一个线程进入,执行完毕后自动解锁,其他县城才可以进来执行。
格式:
**锁对象要求:**理论上,锁对象只要对于当前同时执行的线程来说是同一个对象即可。
package com.itheima.d4_thread_synchronized_code;
/**
账户类:余额,卡号
*/
public class Account {
private String cardId;
private double money; // 余额 关键信息
public Account() {
}
public Account(String cardId, double money) {
this.cardId = cardId;
this.money = money;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
// // 100个线程人
// public static void run(){
// synchronized (Account.class){
//
// }
// }
/**
小明 小红
*/
public void drawMoney(double money) {
// 1、拿到是谁来取钱
String name = Thread.currentThread().getName();
// 同步代码块
// 小明 小红
// this == acc 共享账户
synchronized (this) {
// 2、判断余额是否足够
if(this.money >= money){
// 钱够了
System.out.println(name+"来取钱,吐出:" + money);
// 更新余额
this.money -= money;
System.out.println(name+"取钱后,余额剩余:" + this.money);
}else{
// 3、余额不足
System.out.println(name+"来取钱,余额不足!");
}
}
}
}
<aside> 💡 锁对象要是唯一的吗?
类名.class
(字节码)作为锁对象。
</aside>synchronized(this)
):
synchronized(this)
时,你实际上是在锁定当前对象的实例。这意味着,当一个线程执行了这个同步块时,它会获取当前对象的锁。其他任何线程在尝试执行同一个对象上的任何同步方法时,都必须等待这个锁被释放。这种方式通常用于保护实例变量,确保在任何时候只有一个线程可以修改或访问这些变量。synchronized(MyClass.class)
):
Class
对象作为锁。当你在一个静态方法中使用synchronized(MyClass.class)
时,你锁定的是整个类的Class
对象。这意味着,任何线程在执行这个同步块时,都会获取这个类的锁。在同步块执行期间,其他线程无法执行任何使用这个类锁的同步方法,无论是静态的还是实例的。在实际应用中,你应该根据需要保护的资源的类型和范围来选择合适的锁对象。如果只需要保护单个对象的状态,使用实例对象锁(synchronized(this)
)通常是更好的选择。如果需要保护整个类的资源,或者确保某个操作在整个类中是唯一的,那么类对象锁(synchronized(MyClass.class)
)可能更合适。
**作用:**把出现线程安全问题的核心方法给上锁。 **原理:**每次只能一个线程进入,执行完毕以后自动解锁,其他线程才可以进来执行。
this
作为的锁对象。但是代码要高度面向对象!