抛砖引玉,写了一个lock free的,经grass的指点,终于写对了... class Account {
private final AtomicLong value = new AtomicLong();
public Account(double b) { this.value.set(Double.doubleToLongBits(b)); }
public double getBalance() { return Double.longBitsToDouble(value.get()); }
public void transferMoneyLockFree(double amount) {
while (true) { double oldBalance = this.getBalance(); double newBalance = amount+oldBalance; if (amount<0 && newBalance<0) throw new IllegalArgumentException("can't transfer "+ amount+". Not enough balance");
if (value.compareAndSet(Double.doubleToLongBits( oldBalance), Double.doubleToLongBits(newBalance))) break; } } } public final class TransferFundsBetweenAccounts {
public static final void transferFund(Account from, Account to, double amount) { if (amount==0) return;
if (amount<0) { transferFund(to, from, -amount); return; }
try {
from.transferMoneyLockFree(-amount);
to.transferMoneyLockFree(amount);
} catch (IllegalArgumentException e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { final Account a = new Account(1000); final Account b = new Account(1000);
ExecutorService exec = Executors.newCachedThreadPool(); int n = 1000;
long t = System.currentTimeMillis(); for(int i=0; iexec.execute(new Runnable(){ public void run() { TransferFundsBetweenAccounts. transferFund(a, b, 1); } });
for(int i=0; iexec.execute(new Runnable(){ public void run() { TransferFundsBetweenAccounts. transferFund(b, a, 1); } }); exec.shutdown(); exec.awaitTermination(10, TimeUnit.SECONDS); t = System.currentTimeMillis() - t;
System.out.println("balance of a = " + a.getBalance()); System.out.println("balance of b = " + b.getBalance()); System.out.println("run time = " + t + " mili sec"); } }