一、有锁实现
package com.learning.share_resource;
import lombok.extern.slf4j.Slf4j;
import java.util.LinkedList;
import java.util.List;
/**
* @Author wangyouhui
* @Description 加锁的共享资源
**/
@Slf4j
public class AccountWithLock {
private Integer account;
public AccountWithLock(Integer account){
this.account = account;
}
public void withdraw(Integer amount){
synchronized (this){
this.account -= amount;
}
}
public Integer getAccount(){
return this.account;
}
public static void main(String[] args) {
AccountWithLock accountWithLock = new AccountWithLock(10000);
List<Thread> list = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
list.add(new Thread(()->{
accountWithLock.withdraw(10);
}));
}
long start = System.currentTimeMillis();
list.forEach(Thread::start);
list.forEach(t->{
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
long end = System.currentTimeMillis();
log.info("余额为:{}",accountWithLock.getAccount());
log.info("耗时为:{}", end-start);
}
}
二、无锁实现
package com.learning.share_resource;
import lombok.extern.slf4j.Slf4j;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @Author wangyouhui
* @Description 无锁的共享资源
**/
@Slf4j
public class AccountWithNoLock {
private AtomicInteger account;
public AccountWithNoLock(Integer account){
this.account = new AtomicInteger(account);
}
public void withdraw(Integer amount){
while(true){
// 获取余额的最新值
int previous = account.get();
// 要修改的余额
int next = previous - amount;
// 真正修改
if(account.compareAndSet(previous, next)){
break;
}
}
}
public Integer getAccount(){
return this.account.get();
}
public static void main(String[] args) {
AccountWithNoLock accountWithLock = new AccountWithNoLock(10000);
List<Thread> list = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
list.add(new Thread(()->{
accountWithLock.withdraw(10);
}));
}
long start = System.currentTimeMillis();
list.forEach(Thread::start);
list.forEach(t->{
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
long end = System.currentTimeMillis();
log.info("余额为:{}",accountWithLock.getAccount());
log.info("耗时为:{}", end-start);
}
}