由于同一进程的多个线程共享同一块存储空间,在带来方便的同时,也带来了访问冲突 的问题。Java 语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线 程同时访问造成的这种问题。这套机制就是 synchronized 关键字。

synchronized 语法结构: 
synchronized(锁对象){
同步代码
}

synchronized 关键字使用时需要考虑的问题:
需要对那部分的代码在执行时具有线程互斥的能力(线程互斥:并行变串行)。
需要对哪些线程中的代码具有互斥能力(通过 synchronized 锁对象来决定)。
它包括两种用法:synchronized 方法和 synchronized 块

  1. synchronized 方法
    通过在方法声明中加入 synchronized 关键字来声明,语法如下: public synchronized void accessVal(int newVal);
    synchronized 在方法声明时使用:放在范围操作符(public)之后,返回类型声明(void) 之前。这时同一个对象下 synchronized 方法在多线程中执行时,该方法是同步的,即一次 只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就 是在 synchronized 方法内部的线程)执行完该方法后,别的线程才能进入。
  2. synchronized 块,synchronized 方法的缺陷:若将一个大的方法声明为 synchronized 将会大大影响效 率。Java 为我们提供了更好的解决办法,那就是 synchronized 块。 块可以让我们精确 地控制到具体的“成员变量”,缩小同步的范围,提高效率。
package com.yqq.app12;

/**
* @Author yqq
* @Date 2021/11/27 23:11
* @Version 1.0
*/

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
* 账户类
*/
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
class Account{
//账号
private String accountNo;
//账户余额
private double balance;

}

/**
* 取款线程
*/
class DrawThread extends Thread{
//账户对象
private Account account;
//取款金额
private double drawMoney;
public DrawThread(String name,Account account,double drawMoney){
super(name);
this.account = account;
this.drawMoney = drawMoney;
}
@Override
public void run() {
synchronized (this.account){
//判断当前余额是否大于或等于取款金额
if (this.account.getBalance() >= this.drawMoney){
System.out.println(this.getName()+" 取款成功!取款:"+this.drawMoney);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//修改余额
this.account.setBalance(this.account.getBalance()-this.drawMoney);
System.out.println("\t当前余额为:"+this.account.getBalance());
}else {
System.out.println(this.getName()+" 取款失败,余额不足");
}
}
}
}
public class DrawMoneyThread {
public static void main(String[] args) {
Account account = new Account("10086",1000);
new DrawThread("科比",account,600).start();
new DrawThread("詹姆斯",account,700).start();
}
}

synchronized 实现同步_java