线程同步:保证多个线程同时读取一个类中的共享数据的线程安全
Java所有对象都有一个内置锁,使用 synchronized 关键字修饰方法或代码块时将为当前对象加锁,一个线程获取锁后,其他线程需要等待该线程执行完毕后解锁。
修饰方法:
Java所有对象都有一个内置锁,使用 synchronized 关键字修饰方法或代码块时将为当前对象加锁,一个线程获取锁后,其他线程需要等待该线程执行完毕后解锁。
修饰方法:
private synchronized void function() {}
修饰代码块:
private void function() {
synchronized (object) {}
}
锁加在 object 对象上面。该对象可以是当前对象(object == this),也可以是当前类的Class对象(object == MyClass.class)
简单例子,多线程操作同一账户
线程类:
public class SynchronizedThread extends Thread {
private Account account;
private int cash;
public SynchronizedThread(String name, Account account, int cash) {
super(name);
this.account = account;
this.cash = cash;
}
@Override
public void run() {
account.plus(cash);
}
public static void main(String[] args) {
Account at = new Account(100);
for (int i = 0; i < 5; i++) {
new SynchronizedThread("A" + i, at, -10).start();
}
}
}
账户类(未同步):
public class Account {
private int money;
public Account(int money) {
this.money = money;
}
// 业务方法
public void plus(int cash) {
try {
int last = money;
Thread.sleep(1); // 模拟一个延迟
money += cash;
System.out.println(Thread.currentThread().getName() + ": 钱包: " + last + " 消费: " + cash + " 余额: " + money);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
未同步时,运行结果:
进行线程同步后:
同步方法:
public synchronized void plus(int cash) {
try {
int last = money;
Thread.sleep(1); // 模拟一个延迟
money += cash;
System.out.println(Thread.currentThread().getName() + ": 钱包: " + last + " 消费: " + cash + " 余额: " + money);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
或同步代码块:
public void plus(int cash) {
try {
synchronized (this) {
int last = money;
Thread.sleep(1); // 模拟一个延迟
money += cash;
System.out.println(Thread.currentThread().getName() + ": 钱包: " + last + " 消费: " + cash + " 余额: " + money);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
运行结果: