多线程教程(二十三) 无锁实现线程安全

多线程教程(二十三) 无锁实现线程安全

题目描述:

总额10000元,1000个人取钱,每人取10块,取完余额刚好为0.

加锁方法
class AccountUnsafe implements Account {
    private Integer balance;
    public AccountUnsafe(Integer balance) {
        this.balance = balance;
    }
    @Override
    public synchronized Integer getBalance() {
        return balance;
    }
    @Override
    public synchronized void withdraw(Integer amount) {
        balance -= amount;
    }
}

结果为:

0 cost: 399 ms		
无锁解决方案
class AccountSafe implements Account {
    private AtomicInteger balance;
    public AccountSafe(Integer balance) {
        this.balance = new AtomicInteger(balance);
    }
    @Override
    public Integer getBalance() {
        return balance.get();
    }
    @Override
    public void withdraw(Integer amount) {
        while (true) {
            int prev = balance.get();
            int next = prev - amount;
            if (balance.compareAndSet(prev, next)) {
                break;
            }
        }
        // 可以简化为下面的方法
        // balance.addAndGet(-1 * amount);
    }
}

执行测试代码

public static void main(String[] args) {
    Account.demo(new AccountSafe(10000));
}

某次的执行结果

0 cost: 302 ms

实际上无锁的解决方案就是使用cas,在进行赋值之前对线程内部变量和主线程的变量进行比较,当相同时进行赋值,避免锁的使用

不过这种方案适合线程数量较少的情况,因为线程多了之后cas会一直不成功,降低性能。

你可能感兴趣的:(多线程教程,安全,java,开发语言)