【问题标题】:Two threads enter a synchronized block两个线程进入一个同步块
【发布时间】:2020-01-28 10:03:02
【问题描述】:

我有一个用 synchronized(this) 包裹的块,我在调试模式和日志中都看到 2 个线程同时进入此部分。

public void dispatch(Event.Builder eventBuilder) {

    synchronized (this) {
        index++;
        getLogger().d(TAG, "race condition line A - The index is " + index);

        try {
            Event event = eventBuilder.build();
            getLogger().d(TAG, "race condition line B - The index is " + index);
            mDispatcher.dispatch(event);

        } catch (InstantiationWithoutBuilderException e) {

            // Dev time Exception. Should be caught by Developer
            throw e;
        } catch (StateMachineException e) {

            if (!e.wasWrittenToErrorHistory()) {
                printError(new ExceptionHistoryElement(mState, eventBuilder.getTemporaryEventWithTypeForException(), e));
            }
        } catch (Exception e) {

            printError(new ExceptionHistoryElement(mState, eventBuilder.getTemporaryEventWithTypeForException(), e));
        }
        getLogger().d(TAG, "race condition line C - The index is " + index);
    }
}

日志:

race condition line A - The index is 1
race condition line B - The index is 1
race condition line A - The index is 2
race condition line B - The index is 2
race condition line C - The index is 2
race condition line A - The index is 3
race condition line B - The index is 3
race condition line C - The index is 3
race condition line C - The index is 3
race condition line A - The index is 4
race condition line B - The index is 4
race condition line C - The index is 4
race condition line A - The index is 5
race condition line B - The index is 5
race condition line C - The index is 5

如您所见,每次进入同步块时,我都会增加数据成员索引。 它应该为每个索引打印 3 个日志行, 但正如您在日志中看到的那样,索引 1 打印了两次,索引 3 打印了 4 次。

谢谢

更新: 事实证明它正在发生,因为同一个线程多次进入此方法。同步块仅适用于不同线程之间。这是如何在同步代码中发生的,这是新的谜。

【问题讨论】:

  • 您在运行时是否有多个StateMachine 实例?
  • @Michael 一个人对另一个人说:“呃,你。好像我没有足够的能力来抗衡。”
  • 我用文本代码编辑并替换了屏幕截图

标签: java android synchronization race-condition synchronized


【解决方案1】:

看起来您的线程使用您的 StateMachine 的不同实例。当您在this 上同步时,您使用您的类的特定实例作为监视器。这意味着只有当线程 A 都运行相同的 StateMachine 实例时,线程 A 才会被阻塞等待线程 B。

【讨论】:

  • 我正在使用这个类的一个孩子,它是一个单音。肯定不是多个实例
猜你喜欢
  • 2015-03-02
  • 2013-09-12
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多