当前位置: 首页 > 知识库问答 >
问题:

在两个String对象上同步

太叔鸿博
2023-03-14

我只在一个字符串对象上找到了同步的答案,而不是两个。

这不是一项真正的任务,而是一项任务。我有一个图书馆可以把钱从一个账户转到另一个账户。我无法访问帐户对象以锁定它。我只能用图书馆里的东西。传输(字符串从、字符串到),这不是线程安全的。我有一个帐户ID为字符串的方法。我需要在没有死锁的情况下锁定这两个字符串。

到目前为止,我所做的是:

>

  • 使用创建了新字符串。intern方法(字符串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);
                }
            }
        }
    
  • 共有1个答案

    詹杰
    2023-03-14

    可以使用嵌套的同步块在两个对象上同步。为了防止任何死锁,我将按字典顺序比较这两个字符串:

    public void transfer(String from, String to, int amount) {
            int comparingResult = from.compareTo(to);
            
            if (comparingResult > 0) {
                synchronized (from) {
                    synchronized (to) {
                        SomeLibrary.transfer(from, to);
                    }
                }
            } else if (comparingResult < 0) {
                synchronized (to) {
                    synchronized (from) {
                        SomeLibrary.transfer(from, to);
                    }
                }
            } else {
                if (from == to) { // Do not use equals() here
                    synchronized (from) {
                        SomeLibrary.transfer(from, to);
                    }
                } else {
                    throw new UnsupportedOperationException();
                }
               
            }
        }
    

    else部分是可选的,这取决于您可以在同一个帐户之间转移资金这一事实,在我看来,这有点无用。

     类似资料:
    • 问题内容: 我想知道如果在同一个对象上同步两次,在Java中是否会出现任何奇怪的行为? 场景如下 两种方法都使用该对象并对其进行同步。当第一个方法调用第二个方法时,它会被锁定而停止吗? 我不这么认为,因为它是同一个线程,但是我不确定是否可能会出现其他任何奇怪的结果。 问题答案: 同步块使用 可重入 锁,这意味着如果线程已经持有该锁,则它可以重新获取它而不会出现问题。因此,您的代码将按预期工作。 请

    • 问题内容: 我有一个Web应用程序正在进行负载/性能测试,特别是在一项功能上,我们希望数百名用户正在访问同一页面,并且每10秒刷新一次。我们发现可以使用此功能进行改进的一个方面是,由于数据未更改,因此将Web服务的响应缓存了一段时间。 在实现了基本的缓存之后,在进一步的测试中,我发现我没有考虑并发线程如何同时访问缓存。我发现在大约100毫秒内,约有50个线程试图从缓存中获取对象,发现对象已过期,点

    • 我需要在账户之间实现一些基本的资金转移逻辑。为了保持转账的一致性,我利用了同步锁。 这是帐户对象: 这是在transfer worker类中: 我的问题是,如果source Account没有足够的资金,我计划等待该线程,直到它从其他运营中获得资金。对于这个,我一直在等待源帐户。但它以死锁告终,因为目标帐户锁仍在我的帐户上。我怎样才能做到这一点?你能告诉我解决这个问题的正确方法吗? 这就是我试图推

    • 问题内容: 我和我的朋友正在讨论Strings,而我们坚持了这一点: 他说总共将创建三个对象,而我说将创建一个对象。 他在3个对象之后的逻辑是:一个用于“ ObjectOne”,一个用于“ ObjectTwo”,第三个是两个String对象的串联版本。 我在一个对象后面的逻辑是在编译时,两个字符串对象都将在字节码中串联为: 并且在运行时,将仅以这种方式创建一个对象。这背后的真相是什么? 问题答案:

    • 假设我们有两个类A、B和各自类的同步方法methodA、methodB。如果我们从synchronizedmethodA调用synchronized methodB,那么当methodB仍在执行时,线程是否仍对ObjectA保持锁定?

    • 我有三节课: 人类 父亲 孩子。 儿童阶级延伸父亲,父亲延伸人类。 我已经创建了每个类的一些实例并将它们存储到ArrayList中。 现在,我想编写一个方法来检查对象father1是否与对象child1地址字段(类Father和Child的实例)具有相同的字段地址(例如:“21 str Goodwin”),并将此方法提供给我的ArrayList,如果发现任何结果,则打印。 我怎么能这样呢? 为了更