【发布时间】:2022-01-16 23:08:45
【问题描述】:
我只找到了一个 String 对象同步的答案,而不是两个。
这不是一项真正的任务,而是一项任务。我有 SomeLibrary 可以将钱从一个帐户转移到另一个帐户。我无法访问 Account 对象来锁定它。我只能使用 SomeLibrary.transfer(String from, String to),它不是线程安全的。我有将帐户 ID 作为字符串的方法。我需要在没有死锁的情况下锁定这两个字符串。
到目前为止我所做的是:
-
使用 .intern 方法创建新字符串(String fr = from.intern())。但这是不好的做法,我不允许使用这种方法。但它奏效了。
-
从旧字符串创建新字符串 (String fr = new String(from))。这也有效(我没有死锁),但我对这个解决方案有怀疑。
还有其他方法可以同时锁定两个字符串吗?
我尝试使用 ConcurrentHashMap 并将字符串放在那里,但它不起作用。
可能有一种方法可以将字符串放入某些对象中,但是应该在哪里创建这些对象?我可以在 transfer() 中创建它们,但在局部变量上同步也不是好习惯。
我的方法是:
public void transfer(String from, String to, int amount) {
String fr = new String(from);
String too = new String(to);
int fromHash = System.identityHashCode(fr);
int toHash = System.identityHashCode(too);
if (fromHash < toHash) {
synchronizedTransfer(from, to, amount, fr, too);
} else if (fromHash > toHash) {
synchronizedTransfer(to, from, amount, too, fr);
} else {
synchronized (tieLock) {
synchronizedTransfer(from, to, amount, fr, too);
}
}
}
private void synchronizedTransfer(String from, String to, int amount, String fr, String too) {
synchronized (fr) {
synchronized (too) {
SomeLibrary.transfer(from, to);
}
}
}
编辑:
有没有办法在没有 ConcurrentHashMap 的情况下做到这一点?因为这张地图可能会变得非常大,而且对性能不利
【问题讨论】:
-
尝试使用 StringBuffer。 docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html
标签: java string concurrency synchronization