目录
原子性变量
原子性变量使用Compare and Set(CAS)操作。(先取旧值,然后以新值取代旧值,若旧值不一致,则重新取旧值,反复操作直到成功。)
- AtomicLong: 可进行原子操作的变量
- LongAdder: 效率更高的原子操作变量,使用N个累加数实现。
- LongAccumulator:效率更高的原子操作变量,使用累加“操作”实现。
一、主程序
package xyz.jangle.thread.test.n7_8.atomic;
/**
* 7.8、原子性变量
* AtomicLong: 可进行原子操作的变量
* LongAdder: 效率更高的原子操作变量,使用N个累加数实现。
* LongAccumulator:效率更高的原子操作变量,使用累加“操作”实现。
*
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年9月16日 下午5:56:18
*
*/
public class M {
public static void main(String[] args) {
var account = new Account();
account.setBalance(999);
var company = new Company(account);
var bank = new Bank(account);
var companyThread = new Thread(company);
var bankThread = new Thread(bank);
System.out.println("初始金额" + account.getBalance());
companyThread.start();
bankThread.start();
try {
companyThread.join();
bankThread.join();
System.out.println("balance:" + account.getBalance());
System.out.println("operation:" + account.getOperations());
System.out.println("commission:" + account.getCommission());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
二、模拟银行账户
package xyz.jangle.thread.test.n7_8.atomic;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.DoubleAccumulator;
import java.util.concurrent.atomic.LongAdder;
/**
* 模拟银行账户
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年9月16日 下午5:58:02
*
*/
public class Account {
private final AtomicLong balance;
private final LongAdder operations;
private final DoubleAccumulator commission;
public Account() {
super();
this.balance = new AtomicLong();
this.operations = new LongAdder();
this.commission = new DoubleAccumulator((x, y) -> x + y * 0.2, 0);
}
public AtomicLong getBalance() {
return balance;
}
public LongAdder getOperations() {
return operations;
}
public DoubleAccumulator getCommission() {
return commission;
}
public void setBalance(long balance) {
this.balance.set(balance);
operations.reset();
commission.reset();
}
/**
* 增加账户余额
*
* @param amount
*/
public void addAmount(long amount) {
this.balance.getAndAdd(amount);
this.operations.increment();
this.commission.accumulate(amount);
System.out.println(this.balance.get());
}
/**
* 减少账户余额
*
* @param amount
*/
public void subtractAmount(long amount) {
this.balance.getAndAdd(-amount);
this.operations.increment();
this.commission.accumulate(amount);
System.out.println(this.balance.get());
}
}
三、模拟公司付款
package xyz.jangle.thread.test.n7_8.atomic;
/**
* 模拟公司付款
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年9月16日 下午7:05:52
*
*/
public class Company implements Runnable {
private final Account account;
public Company(Account account) {
super();
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
account.addAmount(1000);
}
}
}
四、模拟银行扣款
package xyz.jangle.thread.test.n7_8.atomic;
/**
* 模拟银行扣款
*
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年9月16日 下午7:07:33
*
*/
public class Bank implements Runnable {
private final Account account;
public Bank(Account account) {
super();
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
account.subtractAmount(1000);
}
}
}
五、执行结果
初始金额999
999
1999
2999
3999
4999
5999
6999
7999
8999
9999
9999
8999
7999
6999
5999
4999
3999
2999
1999
999
balance:999
operation:20
commission:4000.0