Redian新闻
>
问个thread synchronization的问题
avatar
问个thread synchronization的问题# JobHunting - 待字闺中
r*e
1
void transaction(Account a, Account b, double amount)
想从a 转钱到b。怎么设计实现efficient的synchronization。
code in java
avatar
g*e
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

avatar
r*e
3
当然,潜在的问题是,设计的方法不能有deadlock。
avatar
r*e
4
顺便问个keyword final的问题。
为什么local variable 使用final之后,就可以被inner class使用了?
avatar
r*e
5
他说efficient的意思是不让直接用 synchronized modify 这个method

【在 g**e 的大作中提到】
: read java concurrancy in practice
: efficient事小,dead lock事大

avatar
g*e
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.
avatar
g*e
9
barcap这么多年还在问这个题?

【在 r**e 的大作中提到】
: 他说efficient的意思是不让直接用 synchronized modify 这个method
avatar
s*n
10
答案是什么?我想用spinlock但是估计 不对。

【在 g**e 的大作中提到】
: barcap这么多年还在问这个题?
avatar
g*e
11
这题怎么用lock free的方法做我不会,我觉得必须要用synchronize。为了避免dead
lock可以比较两个account的identityHashCode,保证每次锁的顺序一样。
lock free的方法请大牛来解答

【在 s*****n 的大作中提到】
: 答案是什么?我想用spinlock但是估计 不对。
avatar
a*2
12
compare and swap?
avatar
g*s
13
that's enough.
除非需要毫秒级的latency,否则这里没有必要用lockfree

【在 g**e 的大作中提到】
: 这题怎么用lock free的方法做我不会,我觉得必须要用synchronize。为了避免dead
: lock可以比较两个account的identityHashCode,保证每次锁的顺序一样。
: lock free的方法请大牛来解答

avatar
g*e
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; 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");
}
}

dead

【在 g***s 的大作中提到】
: that's enough.
: 除非需要毫秒级的latency,否则这里没有必要用lockfree

avatar
T*e
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 造成的损害就更
大了。。。
avatar
g*e
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 造成的损害就更
: 大了。。。

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。