【问题标题】:Variable that can be read by all Async Tasks所有异步任务都可以读取的变量
【发布时间】:2015-06-26 16:53:36
【问题描述】:

我正在尝试做的是在打印数组时跟踪变量。然而,令人困惑的是它是异步的。

这和我现在的差不多。

public static int variable = 0;

public void print()
{
    System.out.println(array[variable]);
    variable ++;
}

然后是另一个具有 ExecutorService 和 CompletionService 的类,它异步调用 print() 方法,它使用 4 个线程运行大约 40 个作业(在我的示例中是 11 个作业)。

问题(我怎么看)是因为它是异步运行的,所以 4 个线程具有相同的变量值,或者它跳过了一些值,因为 2 个线程同时完成,因此它增加了 2。

我打印了变量值,下面是一些结果:

  1. 0 1 2 2 2 2 6 6 6 9 10
  2. 0 1 2 2 4 4 6 7 8 9 10
  3. 0 1 1 1 1 5 6 7 8 8 8

【问题讨论】:

  • 为什么variable 是全球性的?如果是本地的,线程就不会相互干扰。
  • @tschwab 我希望它是全局的,这样每个线程都会得到更新的变量。就像如果一个线程将 1 添加到变量,那么其他线程会知道,因此下一个线程将打印 2。编辑:我尝试将其设为本地,但没有帮助:\

标签: java multithreading asynchronous


【解决方案1】:

声明方法print()同步。 或者将变量 variable 声明为 AtomicInteger 而不是 int。

【讨论】:

  • 哇 AtomicInteger 很棒,但是,它并没有解决我的问题。我将代码更改为:AtmoicInteger variable = new AtomicInteger(0)System.out.println(array[variable.addAndIncrement)。这些是3 3 3 4 11 11 11 11 11 11 113 5 6 7 11 11 11 11 11 11 11 的结果 编辑:我试过同步,但也没有用
  • 关键是你必须在print()运行时锁定variable。声明 print() synchronized 应该可以工作。
  • @tschwab 我认为它不起作用,因为当它锁定时,它会用 4 个其他线程锁定变量,所以它们有可能都锁定了相同的数字?线程同时运行(据我了解)
  • "同一对象上同步方法的两次调用不可能交错。"我猜不同的对象正在调用print() 函数?一个可能的解决方案是创建一个处理打印的新对象。
  • @tschwab 你明白了。不同的对象调用了 print 函数,我只是改变了它,只调用了一个对象。如果你用你所说的做了另一个答案(包括同步!这有很大的不同),我很乐意选择你的答案:D 感谢您的帮助!编辑:(NVM 生病只是将此标记为答案!)
【解决方案2】:

您可以创建一个处理打印的新类:

public class SyncPrinter {
    public static int variable = 0;

    public static synchronized void print()
    {
        System.out.println(array[variable]);
        variable ++;
    }
}

那就叫SyncPrinter.print()

【讨论】:

  • 等等,为什么要创建一个新课程?这门课和我已有的一样。
猜你喜欢
  • 2018-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-12
  • 2015-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多