【问题标题】:Why isnt this counter class "thread safe"为什么这个计数器类不是“线程安全的”
【发布时间】:2017-10-22 04:04:47
【问题描述】:

我试图弄清楚为什么这不是“线程安全的”并且我正在公开绘制空白

public class Counter {
private static int val = 0;

public Counter() {
}

public static void set(int newVal) {
    val = newVal;
}

public static void decrement() {
    int tmp = val;

    try {
        Thread.sleep(100L);
    } catch (Exception var2) {
        ;
    }

    --tmp;
    val = tmp;
}

public static boolean depleted() {
    return val == 0;
}
}

是不是因为做了很多 Counters 就不能正常工作?例如,一群角色使用 Counter 进行移动。如果一个角色没有动作可以做,那么一个新角色开始做动作。实现 Counter 的所有字符都不允许 Counter 正常工作吗?它与线程安全有什么关系?

【问题讨论】:

  • 你似乎不明白什么是线程安全...阅读一下here

标签: java multithreading thread-safety


【解决方案1】:

是不是因为做了很多 Counters 就不能正常工作?

没有。这不是线程安全的意思。

假设某个程序P 可以说是正确,如果它总是满足一组条件C。线程安全意味着如果程序P 对一个线程是正确的,那么它对多个线程也是正确的。更详细的解释可以在thread safety 上的维基百科文章中找到。

在此示例中,代码设计旨在实现将由整个应用程序共享的单个计数器。如果这不是所需要的,那就是一个问题。但是,问题在于代码根据隐含要求(针对多个计数器)不正确,而不是线程安全。

此代码存在线程安全问题。具体来说,如果两个或更多线程使用此类,则代码将无法正常工作……作为单个共享计数器。例如,一个线程可能看不到另一个线程所做的更新,或者减量可能会丢失。问题是线程将在没有正确同步的情况下使用共享变量(即val)。如果没有同步,那么你可以获得竞争条件内存异常

【讨论】:

  • 非常感谢。为了进一步理解,我试图实现它以确切了解如果两个线程如何使用它,那么它将无法正常工作。我可以做哪些简单的实现来查看它的实际效果并证明它不是线程安全的?
  • 摆脱sleep 调用,然后只需编写一个多线程应用程序,从多个线程快速执行大量操作......并寻找异常答案。如果您遇到异常,您(可能)证明它不是线程安全的。 (但如果你没有看到异常,你就没有证明代码是线程安全的!!)
  • 很难证明代码是线程安全的。它需要对代码进行详细的分析,并对 Java 内存模型 (JMM) 有深入的了解。
猜你喜欢
  • 2015-07-24
  • 2018-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多