r**e 发帖数: 226 | 1 void transaction(Account a, Account b, double amount)
想从a 转钱到b。怎么设计实现efficient的synchronization。
code in java |
g**e 发帖数: 6127 | 2 read java concurrancy in practice
efficient事小,dead lock事大
【在 r**e 的大作中提到】 : void transaction(Account a, Account b, double amount) : 想从a 转钱到b。怎么设计实现efficient的synchronization。 : code in java
|
r**e 发帖数: 226 | 3 当然,潜在的问题是,设计的方法不能有deadlock。 |
r**e 发帖数: 226 | 4 顺便问个keyword final的问题。
为什么local variable 使用final之后,就可以被inner class使用了? |
r**e 发帖数: 226 | 5 他说efficient的意思是不让直接用 synchronized modify 这个method
【在 g**e 的大作中提到】 : read java concurrancy in practice : efficient事小,dead lock事大
|
g**e 发帖数: 6127 | 6 http://mitbbs.com/article1/Java/31120293_3_0.html
【在 r**e 的大作中提到】 : 顺便问个keyword final的问题。 : 为什么local variable 使用final之后,就可以被inner class使用了?
|
r**e 发帖数: 226 | 7 I saw this. But honestly, I am not convinced by his answer.
【在 g**e 的大作中提到】 : http://mitbbs.com/article1/Java/31120293_3_0.html
|
g**e 发帖数: 6127 | 8 then u should see goodbug's answer too.
that is the correct answer.
【在 r**e 的大作中提到】 : I saw this. But honestly, I am not convinced by his answer.
|
|
g**e 发帖数: 6127 | 9 barcap这么多年还在问这个题?
【在 r**e 的大作中提到】 : 他说efficient的意思是不让直接用 synchronized modify 这个method
|
s*****n 发帖数: 5488 | 10 答案是什么?我想用spinlock但是估计 不对。
【在 g**e 的大作中提到】 : barcap这么多年还在问这个题?
|
|
|
g**e 发帖数: 6127 | 11 这题怎么用lock free的方法做我不会,我觉得必须要用synchronize。为了避免dead
lock可以比较两个account的identityHashCode,保证每次锁的顺序一样。
lock free的方法请大牛来解答
【在 s*****n 的大作中提到】 : 答案是什么?我想用spinlock但是估计 不对。
|
a**********2 发帖数: 340 | |
g***s 发帖数: 3811 | 13 that's enough.
除非需要毫秒级的latency,否则这里没有必要用lockfree
【在 g**e 的大作中提到】 : 这题怎么用lock free的方法做我不会,我觉得必须要用synchronize。为了避免dead : lock可以比较两个account的identityHashCode,保证每次锁的顺序一样。 : lock free的方法请大牛来解答
|
g**e 发帖数: 6127 | 14 抛砖引玉,写了一个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; i
exec.execute(new Runnable(){
public void run() {
TransferFundsBetweenAccounts.
transferFund(a, b, 1);
}
});
for(int i=0; i
exec.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");
}
}
dead
【在 g***s 的大作中提到】 : that's enough. : 除非需要毫秒级的latency,否则这里没有必要用lockfree
|
T********e 发帖数: 3677 | 15 有个小问题:
from.transferMoneyLockFree(-amount);
to.transferMoneyLockFree(amount);
这是两个transaction,如果system crash in the middle, 那么from account 里面的
钱被扣除了, 而还没有来的及转移到to account 里面。
在transferMoneyLockFree()function里面用了while loop, 直到transfer成功为止
, system busy的时候,from和to很可能有很多lag, system crash 造成的损害就更
大了。。。 |
g**e 发帖数: 6127 | 16 你说的对,真正做时候,是要用transaction实现的,一出问题就roll back。
第二个问题是不存在的,cas效率很高,比synchronized快
【在 T********e 的大作中提到】 : 有个小问题: : from.transferMoneyLockFree(-amount); : to.transferMoneyLockFree(amount); : 这是两个transaction,如果system crash in the middle, 那么from account 里面的 : 钱被扣除了, 而还没有来的及转移到to account 里面。 : 在transferMoneyLockFree()function里面用了while loop, 直到transfer成功为止 : , system busy的时候,from和to很可能有很多lag, system crash 造成的损害就更 : 大了。。。
|